diff options
| author | Jim Blandy | 1992-01-13 21:48:03 +0000 |
|---|---|---|
| committer | Jim Blandy | 1992-01-13 21:48:03 +0000 |
| commit | d427b66a664c0e1ffc818dfa5b87b45b4857d2ae (patch) | |
| tree | a3255be5cf521ab9c44b9fdfd06a0466274be421 /src | |
| parent | b2c9579f172da05112f29b664de6d8da98c1e813 (diff) | |
| download | emacs-d427b66a664c0e1ffc818dfa5b87b45b4857d2ae.tar.gz emacs-d427b66a664c0e1ffc818dfa5b87b45b4857d2ae.zip | |
entered into RCS
Diffstat (limited to 'src')
| -rw-r--r-- | src/XTests.c | 48 | ||||
| -rw-r--r-- | src/XTests.h | 7 | ||||
| -rw-r--r-- | src/abbrev.c | 45 | ||||
| -rw-r--r-- | src/acldef.h | 40 | ||||
| -rw-r--r-- | src/casefiddle.c | 3 | ||||
| -rw-r--r-- | src/casetab.c | 10 | ||||
| -rw-r--r-- | src/chpdef.h | 38 | ||||
| -rw-r--r-- | src/cm.c | 414 | ||||
| -rw-r--r-- | src/disptab.h | 82 | ||||
| -rw-r--r-- | src/doprnt.c | 4 | ||||
| -rw-r--r-- | src/indent.h | 34 | ||||
| -rw-r--r-- | src/insdel.c | 20 | ||||
| -rw-r--r-- | src/ioctl.h | 1 | ||||
| -rw-r--r-- | src/lastfile.c | 38 | ||||
| -rw-r--r-- | src/line.h | 7 | ||||
| -rw-r--r-- | src/macros.h | 31 | ||||
| -rw-r--r-- | src/marker.c | 12 | ||||
| -rw-r--r-- | src/mocklisp.c | 8 | ||||
| -rw-r--r-- | src/mocklisp.h | 2 | ||||
| -rw-r--r-- | src/ndir.h | 51 | ||||
| -rw-r--r-- | src/param.h | 2 | ||||
| -rw-r--r-- | src/point.h | 5 | ||||
| -rw-r--r-- | src/pre-crt0.c | 9 | ||||
| -rw-r--r-- | src/puresize.h | 12 | ||||
| -rw-r--r-- | src/sink.h | 91 | ||||
| -rw-r--r-- | src/sink11.h | 51 | ||||
| -rw-r--r-- | src/sink11mask.h | 51 | ||||
| -rw-r--r-- | src/terminfo.c | 50 | ||||
| -rw-r--r-- | src/uaf.h | 23 | ||||
| -rw-r--r-- | src/unexconvex.c | 601 | ||||
| -rw-r--r-- | src/unexelf.c | 703 | ||||
| -rw-r--r-- | src/unexenix.c | 262 | ||||
| -rw-r--r-- | src/unexhp9k800.c | 6 | ||||
| -rw-r--r-- | src/vlimit.h | 2 | ||||
| -rw-r--r-- | src/vms-pp.c | 2 | ||||
| -rw-r--r-- | src/vms-pwd.h | 34 | ||||
| -rw-r--r-- | src/vmsdir.h | 97 | ||||
| -rw-r--r-- | src/vmsfns.c | 14 | ||||
| -rw-r--r-- | src/vmsmap.c | 224 | ||||
| -rw-r--r-- | src/vmspaths.h | 15 | ||||
| -rw-r--r-- | src/vmsproc.c | 6 | ||||
| -rw-r--r-- | src/vmsproc.h | 21 | ||||
| -rw-r--r-- | src/xscrollbar.h | 123 |
43 files changed, 3194 insertions, 105 deletions
diff --git a/src/XTests.c b/src/XTests.c index 9c1d3666bdb..4147ecd35d6 100644 --- a/src/XTests.c +++ b/src/XTests.c | |||
| @@ -67,8 +67,8 @@ main (argc,argv) | |||
| 67 | int depth; | 67 | int depth; |
| 68 | Pixmap pix; | 68 | Pixmap pix; |
| 69 | char *string = "Kill the head and the body will die."; | 69 | char *string = "Kill the head and the body will die."; |
| 70 | char dash_list[] = {6, 4, 6, 4}; | 70 | char dash_list[] = {4, 4}; |
| 71 | int dashes = 4; | 71 | int dashes = 2; |
| 72 | 72 | ||
| 73 | if (argc < 2) | 73 | if (argc < 2) |
| 74 | dpy_string = "localhost:0.0"; | 74 | dpy_string = "localhost:0.0"; |
| @@ -105,24 +105,19 @@ main (argc,argv) | |||
| 105 | &gc_values); | 105 | &gc_values); |
| 106 | 106 | ||
| 107 | gc_values.foreground = obtain_color ("red"); | 107 | gc_values.foreground = obtain_color ("red"); |
| 108 | gc_values.function = GXor; | ||
| 109 | gc_values.line_width = 3; | 108 | gc_values.line_width = 3; |
| 110 | gc_values.line_style = LineOnOffDash; | 109 | gc_values.line_style = LineOnOffDash; |
| 111 | gc_values.cap_style = CapRound; | 110 | gc_values.cap_style = CapRound; |
| 112 | gc_values.join_style = JoinRound; | 111 | gc_values.join_style = JoinRound; |
| 113 | line_xor_gc = XCreateGC (dpy, window, | 112 | line_xor_gc = XCreateGC (dpy, window, |
| 114 | GCForeground | GCBackground | GCLineStyle | 113 | GCForeground | GCBackground | GCLineStyle |
| 115 | | GCJoinStyle | GCCapStyle | GCLineWidth | 114 | | GCJoinStyle | GCCapStyle | GCLineWidth, |
| 116 | | GCFunction, | ||
| 117 | &gc_values); | 115 | &gc_values); |
| 118 | XSetDashes (dpy, line_xor_gc, 0, dash_list, dashes); | 116 | XSetDashes (dpy, line_xor_gc, 0, dash_list, dashes); |
| 119 | 117 | ||
| 120 | gc_values.background = WhitePixel (dpy, DefaultScreen (dpy)); | ||
| 121 | gc_values.foreground = obtain_color ("blue"); | ||
| 122 | line_xor_inv_gc = XCreateGC (dpy, window, | 118 | line_xor_inv_gc = XCreateGC (dpy, window, |
| 123 | GCForeground | GCBackground | 119 | GCForeground | GCBackground | GCLineWidth, |
| 124 | | GCLineWidth | GCFunction, | 120 | &gc_values); |
| 125 | &gc_values); | ||
| 126 | 121 | ||
| 127 | depth = DefaultDepthOfScreen (ScreenOfDisplay (dpy, DefaultScreen (dpy))); | 122 | depth = DefaultDepthOfScreen (ScreenOfDisplay (dpy, DefaultScreen (dpy))); |
| 128 | pix = XCreateBitmapFromData (dpy, window, page_glyf_bits, | 123 | pix = XCreateBitmapFromData (dpy, window, page_glyf_bits, |
| @@ -137,25 +132,20 @@ main (argc,argv) | |||
| 137 | switch (event.type) | 132 | switch (event.type) |
| 138 | { | 133 | { |
| 139 | case ButtonPress: | 134 | case ButtonPress: |
| 140 | #if 0 | 135 | switch (event.xbutton.button) |
| 141 | if (event.xbutton.state && ShiftMask) | 136 | { |
| 142 | #endif | 137 | case Button1: |
| 143 | switch (event.xbutton.button) | 138 | XDrawLine (dpy, window, line_xor_gc, 25, 75, 300, 75); |
| 144 | { | 139 | break; |
| 145 | case Button1: | 140 | |
| 146 | XDrawLine (dpy, window, line_xor_gc, 25, 75, 125, 75); | 141 | case Button2: |
| 147 | XFlush (dpy); | 142 | XDrawLine (dpy, window, line_xor_inv_gc, 25, 25, 300, 25); |
| 148 | XDrawLine (dpy, window, line_xor_gc, 25, 75, 125, 75); | 143 | break; |
| 149 | break; | 144 | |
| 150 | 145 | case Button3: | |
| 151 | case Button2: | 146 | XDrawLine (dpy, window, line_xor_gc, 25, 25, 25, 125); |
| 152 | XDrawLine (dpy, window, line_xor_gc, 25, 75, 125, 75); | 147 | break; |
| 153 | break; | 148 | } |
| 154 | |||
| 155 | case Button3: | ||
| 156 | XDrawLine (dpy, window, line_xor_gc, 25, 75, 125, 75); | ||
| 157 | break; | ||
| 158 | } | ||
| 159 | break; | 149 | break; |
| 160 | 150 | ||
| 161 | case KeyPress: | 151 | case KeyPress: |
diff --git a/src/XTests.h b/src/XTests.h new file mode 100644 index 00000000000..e91445af7ef --- /dev/null +++ b/src/XTests.h | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | #define page_glyf_width 30 | ||
| 2 | #define page_glyf_height 10 | ||
| 3 | static char page_glyf_bits[] = { | ||
| 4 | 0xf0, 0xff, 0xff, 0x03, 0x08, 0x00, 0x00, 0x04, 0xc4, 0x19, 0xf3, 0x08, | ||
| 5 | 0x42, 0xa5, 0x14, 0x10, 0xc1, 0xa5, 0x70, 0x20, 0x41, 0xbc, 0x16, 0x20, | ||
| 6 | 0x42, 0xa4, 0x14, 0x10, 0x44, 0x24, 0xf3, 0x08, 0x08, 0x00, 0x00, 0x04, | ||
| 7 | 0xf0, 0xff, 0xff, 0x03}; | ||
diff --git a/src/abbrev.c b/src/abbrev.c index 74c0e80010a..9a7640b872c 100644 --- a/src/abbrev.c +++ b/src/abbrev.c | |||
| @@ -20,7 +20,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |||
| 20 | 20 | ||
| 21 | #include "config.h" | 21 | #include "config.h" |
| 22 | #include <stdio.h> | 22 | #include <stdio.h> |
| 23 | #undef NULL | ||
| 24 | #include "lisp.h" | 23 | #include "lisp.h" |
| 25 | #include "commands.h" | 24 | #include "commands.h" |
| 26 | #include "buffer.h" | 25 | #include "buffer.h" |
| @@ -113,9 +112,9 @@ it is called after EXPANSION is inserted.") | |||
| 113 | Lisp_Object sym, oexp, ohook, tem; | 112 | Lisp_Object sym, oexp, ohook, tem; |
| 114 | CHECK_VECTOR (table, 0); | 113 | CHECK_VECTOR (table, 0); |
| 115 | CHECK_STRING (name, 1); | 114 | CHECK_STRING (name, 1); |
| 116 | if (!NULL (expansion)) | 115 | if (!NILP (expansion)) |
| 117 | CHECK_STRING (expansion, 2); | 116 | CHECK_STRING (expansion, 2); |
| 118 | if (NULL (count)) | 117 | if (NILP (count)) |
| 119 | count = make_number (0); | 118 | count = make_number (0); |
| 120 | else | 119 | else |
| 121 | CHECK_NUMBER (count, 0); | 120 | CHECK_NUMBER (count, 0); |
| @@ -126,10 +125,10 @@ it is called after EXPANSION is inserted.") | |||
| 126 | ohook = XSYMBOL (sym)->function; | 125 | ohook = XSYMBOL (sym)->function; |
| 127 | if (!((EQ (oexp, expansion) | 126 | if (!((EQ (oexp, expansion) |
| 128 | || (XTYPE (oexp) == Lisp_String && XTYPE (expansion) == Lisp_String | 127 | || (XTYPE (oexp) == Lisp_String && XTYPE (expansion) == Lisp_String |
| 129 | && (tem = Fstring_equal (oexp, expansion), !NULL (tem)))) | 128 | && (tem = Fstring_equal (oexp, expansion), !NILP (tem)))) |
| 130 | && | 129 | && |
| 131 | (EQ (ohook, hook) | 130 | (EQ (ohook, hook) |
| 132 | || (tem = Fequal (ohook, hook), !NULL (tem))))) | 131 | || (tem = Fequal (ohook, hook), !NILP (tem))))) |
| 133 | abbrevs_changed = 1; | 132 | abbrevs_changed = 1; |
| 134 | 133 | ||
| 135 | Fset (sym, expansion); | 134 | Fset (sym, expansion); |
| @@ -156,7 +155,7 @@ DEFUN ("define-mode-abbrev", Fdefine_mode_abbrev, Sdefine_mode_abbrev, 2, 2, | |||
| 156 | (name, expansion) | 155 | (name, expansion) |
| 157 | Lisp_Object name, expansion; | 156 | Lisp_Object name, expansion; |
| 158 | { | 157 | { |
| 159 | if (NULL (current_buffer->abbrev_table)) | 158 | if (NILP (current_buffer->abbrev_table)) |
| 160 | error ("Major mode has no abbrev table"); | 159 | error ("Major mode has no abbrev table"); |
| 161 | 160 | ||
| 162 | Fdefine_abbrev (current_buffer->abbrev_table, Fdowncase (name), | 161 | Fdefine_abbrev (current_buffer->abbrev_table, Fdowncase (name), |
| @@ -176,19 +175,19 @@ The default is to try buffer's mode-specific abbrev table, then global table.") | |||
| 176 | { | 175 | { |
| 177 | Lisp_Object sym; | 176 | Lisp_Object sym; |
| 178 | CHECK_STRING (abbrev, 0); | 177 | CHECK_STRING (abbrev, 0); |
| 179 | if (!NULL (table)) | 178 | if (!NILP (table)) |
| 180 | sym = Fintern_soft (abbrev, table); | 179 | sym = Fintern_soft (abbrev, table); |
| 181 | else | 180 | else |
| 182 | { | 181 | { |
| 183 | sym = Qnil; | 182 | sym = Qnil; |
| 184 | if (!NULL (current_buffer->abbrev_table)) | 183 | if (!NILP (current_buffer->abbrev_table)) |
| 185 | sym = Fintern_soft (abbrev, current_buffer->abbrev_table); | 184 | sym = Fintern_soft (abbrev, current_buffer->abbrev_table); |
| 186 | if (NULL (XSYMBOL (sym)->value)) | 185 | if (NILP (XSYMBOL (sym)->value)) |
| 187 | sym = Qnil; | 186 | sym = Qnil; |
| 188 | if (NULL (sym)) | 187 | if (NILP (sym)) |
| 189 | sym = Fintern_soft (abbrev, Vglobal_abbrev_table); | 188 | sym = Fintern_soft (abbrev, Vglobal_abbrev_table); |
| 190 | } | 189 | } |
| 191 | if (NULL (XSYMBOL (sym)->value)) return Qnil; | 190 | if (NILP (XSYMBOL (sym)->value)) return Qnil; |
| 192 | return sym; | 191 | return sym; |
| 193 | } | 192 | } |
| 194 | 193 | ||
| @@ -201,7 +200,7 @@ then ABBREV is looked up in that table only.") | |||
| 201 | { | 200 | { |
| 202 | Lisp_Object sym; | 201 | Lisp_Object sym; |
| 203 | sym = Fabbrev_symbol (abbrev, table); | 202 | sym = Fabbrev_symbol (abbrev, table); |
| 204 | if (NULL (sym)) return sym; | 203 | if (NILP (sym)) return sym; |
| 205 | return Fsymbol_value (sym); | 204 | return Fsymbol_value (sym); |
| 206 | } | 205 | } |
| 207 | 206 | ||
| @@ -221,12 +220,12 @@ Returns t if expansion took place.") | |||
| 221 | register Lisp_Object sym; | 220 | register Lisp_Object sym; |
| 222 | Lisp_Object expansion, hook, tem; | 221 | Lisp_Object expansion, hook, tem; |
| 223 | 222 | ||
| 224 | if (!NULL (Vrun_hooks)) | 223 | if (!NILP (Vrun_hooks)) |
| 225 | call1 (Vrun_hooks, Qpre_abbrev_expand_hook); | 224 | call1 (Vrun_hooks, Qpre_abbrev_expand_hook); |
| 226 | 225 | ||
| 227 | if (XBUFFER (Vabbrev_start_location_buffer) != current_buffer) | 226 | if (XBUFFER (Vabbrev_start_location_buffer) != current_buffer) |
| 228 | Vabbrev_start_location = Qnil; | 227 | Vabbrev_start_location = Qnil; |
| 229 | if (!NULL (Vabbrev_start_location)) | 228 | if (!NILP (Vabbrev_start_location)) |
| 230 | { | 229 | { |
| 231 | tem = Vabbrev_start_location; | 230 | tem = Vabbrev_start_location; |
| 232 | CHECK_NUMBER_COERCE_MARKER (tem, 0); | 231 | CHECK_NUMBER_COERCE_MARKER (tem, 0); |
| @@ -267,9 +266,9 @@ Returns t if expansion took place.") | |||
| 267 | sym = oblookup (current_buffer->abbrev_table, buffer, p - buffer); | 266 | sym = oblookup (current_buffer->abbrev_table, buffer, p - buffer); |
| 268 | else | 267 | else |
| 269 | XFASTINT (sym) = 0; | 268 | XFASTINT (sym) = 0; |
| 270 | if (XTYPE (sym) == Lisp_Int || NULL (XSYMBOL (sym)->value)) | 269 | if (XTYPE (sym) == Lisp_Int || NILP (XSYMBOL (sym)->value)) |
| 271 | sym = oblookup (Vglobal_abbrev_table, buffer, p - buffer); | 270 | sym = oblookup (Vglobal_abbrev_table, buffer, p - buffer); |
| 272 | if (XTYPE (sym) == Lisp_Int || NULL (XSYMBOL (sym)->value)) | 271 | if (XTYPE (sym) == Lisp_Int || NILP (XSYMBOL (sym)->value)) |
| 273 | return Qnil; | 272 | return Qnil; |
| 274 | 273 | ||
| 275 | if (INTERACTIVE && !EQ (minibuf_window, selected_window)) | 274 | if (INTERACTIVE && !EQ (minibuf_window, selected_window)) |
| @@ -327,7 +326,7 @@ Returns t if expansion took place.") | |||
| 327 | } | 326 | } |
| 328 | 327 | ||
| 329 | hook = XSYMBOL (sym)->function; | 328 | hook = XSYMBOL (sym)->function; |
| 330 | if (!NULL (hook)) | 329 | if (!NILP (hook)) |
| 331 | call0 (hook); | 330 | call0 (hook); |
| 332 | 331 | ||
| 333 | return Qt; | 332 | return Qt; |
| @@ -367,7 +366,7 @@ write_abbrev (sym, stream) | |||
| 367 | Lisp_Object sym, stream; | 366 | Lisp_Object sym, stream; |
| 368 | { | 367 | { |
| 369 | Lisp_Object name; | 368 | Lisp_Object name; |
| 370 | if (NULL (XSYMBOL (sym)->value)) | 369 | if (NILP (XSYMBOL (sym)->value)) |
| 371 | return; | 370 | return; |
| 372 | insert (" (", 5); | 371 | insert (" (", 5); |
| 373 | XSET (name, Lisp_String, XSYMBOL (sym)->name); | 372 | XSET (name, Lisp_String, XSYMBOL (sym)->name); |
| @@ -387,7 +386,7 @@ describe_abbrev (sym, stream) | |||
| 387 | { | 386 | { |
| 388 | Lisp_Object one; | 387 | Lisp_Object one; |
| 389 | 388 | ||
| 390 | if (NULL (XSYMBOL (sym)->value)) | 389 | if (NILP (XSYMBOL (sym)->value)) |
| 391 | return; | 390 | return; |
| 392 | one = make_number (1); | 391 | one = make_number (1); |
| 393 | Fprin1 (Fsymbol_name (sym), stream); | 392 | Fprin1 (Fsymbol_name (sym), stream); |
| @@ -395,7 +394,7 @@ describe_abbrev (sym, stream) | |||
| 395 | Fprin1 (XSYMBOL (sym)->plist, stream); | 394 | Fprin1 (XSYMBOL (sym)->plist, stream); |
| 396 | Findent_to (make_number (20), one); | 395 | Findent_to (make_number (20), one); |
| 397 | Fprin1 (XSYMBOL (sym)->value, stream); | 396 | Fprin1 (XSYMBOL (sym)->value, stream); |
| 398 | if (!NULL (XSYMBOL (sym)->function)) | 397 | if (!NILP (XSYMBOL (sym)->function)) |
| 399 | { | 398 | { |
| 400 | Findent_to (make_number (45), one); | 399 | Findent_to (make_number (45), one); |
| 401 | Fprin1 (XSYMBOL (sym)->function, stream); | 400 | Fprin1 (XSYMBOL (sym)->function, stream); |
| @@ -424,7 +423,7 @@ define the abbrev table NAME exactly as it is currently defined.") | |||
| 424 | 423 | ||
| 425 | XSET (stream, Lisp_Buffer, current_buffer); | 424 | XSET (stream, Lisp_Buffer, current_buffer); |
| 426 | 425 | ||
| 427 | if (!NULL (readable)) | 426 | if (!NILP (readable)) |
| 428 | { | 427 | { |
| 429 | insert_string ("("); | 428 | insert_string ("("); |
| 430 | Fprin1 (name, stream); | 429 | Fprin1 (name, stream); |
| @@ -457,7 +456,7 @@ of the form (ABBREVNAME EXPANSION HOOK USECOUNT).") | |||
| 457 | 456 | ||
| 458 | CHECK_SYMBOL (tabname, 0); | 457 | CHECK_SYMBOL (tabname, 0); |
| 459 | table = Fboundp (tabname); | 458 | table = Fboundp (tabname); |
| 460 | if (NULL (table) || (table = Fsymbol_value (tabname), NULL (table))) | 459 | if (NILP (table) || (table = Fsymbol_value (tabname), NILP (table))) |
| 461 | { | 460 | { |
| 462 | table = Fmake_abbrev_table (); | 461 | table = Fmake_abbrev_table (); |
| 463 | Fset (tabname, table); | 462 | Fset (tabname, table); |
| @@ -466,7 +465,7 @@ of the form (ABBREVNAME EXPANSION HOOK USECOUNT).") | |||
| 466 | } | 465 | } |
| 467 | CHECK_VECTOR (table, 0); | 466 | CHECK_VECTOR (table, 0); |
| 468 | 467 | ||
| 469 | for (;!NULL (defns); defns = Fcdr (defns)) | 468 | for (;!NILP (defns); defns = Fcdr (defns)) |
| 470 | { | 469 | { |
| 471 | elt = Fcar (defns); | 470 | elt = Fcar (defns); |
| 472 | name = Fcar (elt); | 471 | name = Fcar (elt); |
diff --git a/src/acldef.h b/src/acldef.h new file mode 100644 index 00000000000..cc4085c6aab --- /dev/null +++ b/src/acldef.h | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | #define ACL$K_LENGTH 12 | ||
| 2 | #define ACL$C_LENGTH 12 | ||
| 3 | #define ACL$C_FILE 1 | ||
| 4 | #define ACL$C_DEVICE 2 | ||
| 5 | #define ACL$C_JOBCTL_QUEUE 3 | ||
| 6 | #define ACL$C_COMMON_EF_CLUSTER 4 | ||
| 7 | #define ACL$C_LOGICAL_NAME_TABLE 5 | ||
| 8 | #define ACL$C_PROCESS 6 | ||
| 9 | #define ACL$C_GROUP_GLOBAL_SECTION 7 | ||
| 10 | #define ACL$C_SYSTEM_GLOBAL_SECTION 8 | ||
| 11 | #define ACL$C_ADDACLENT 1 | ||
| 12 | #define ACL$C_DELACLENT 2 | ||
| 13 | #define ACL$C_MODACLENT 3 | ||
| 14 | #define ACL$C_FNDACLENT 4 | ||
| 15 | #define ACL$C_FNDACETYP 5 | ||
| 16 | #define ACL$C_DELETEACL 6 | ||
| 17 | #define ACL$C_READACL 7 | ||
| 18 | #define ACL$C_ACLLENGTH 8 | ||
| 19 | #define ACL$C_READACE 9 | ||
| 20 | #define ACL$C_RLOCK_ACL 10 | ||
| 21 | #define ACL$C_WLOCK_ACL 11 | ||
| 22 | #define ACL$C_UNLOCK_ACL 12 | ||
| 23 | #define ACL$S_ADDACLENT 255 | ||
| 24 | #define ACL$S_DELACLENT 255 | ||
| 25 | #define ACL$S_MODACLENT 255 | ||
| 26 | #define ACL$S_FNDACLENT 255 | ||
| 27 | #define ACL$S_FNDACETYP 255 | ||
| 28 | #define ACL$S_DELETEACL 255 | ||
| 29 | #define ACL$S_READACL 512 | ||
| 30 | #define ACL$S_ACLLENGTH 4 | ||
| 31 | #define ACL$S_READACE 255 | ||
| 32 | #define ACL$S_RLOCK_ACL 4 | ||
| 33 | #define ACL$S_WLOCK_ACL 4 | ||
| 34 | #define ACL$S_UNLOCK_ACL 4 | ||
| 35 | #define ACL$S_ACLDEF 16 | ||
| 36 | #define ACL$L_FLINK 0 | ||
| 37 | #define ACL$L_BLINK 4 | ||
| 38 | #define ACL$W_SIZE 8 | ||
| 39 | #define ACL$B_TYPE 10 | ||
| 40 | #define ACL$L_LIST 12 | ||
diff --git a/src/casefiddle.c b/src/casefiddle.c index d508deb5d60..87dd1c79825 100644 --- a/src/casefiddle.c +++ b/src/casefiddle.c | |||
| @@ -261,7 +261,10 @@ syms_of_casefiddle () | |||
| 261 | keys_of_casefiddle () | 261 | keys_of_casefiddle () |
| 262 | { | 262 | { |
| 263 | initial_define_key (control_x_map, Ctl('U'), "upcase-region"); | 263 | initial_define_key (control_x_map, Ctl('U'), "upcase-region"); |
| 264 | Fput (intern ("upcase-region"), Qdisabled, Qt); | ||
| 264 | initial_define_key (control_x_map, Ctl('L'), "downcase-region"); | 265 | initial_define_key (control_x_map, Ctl('L'), "downcase-region"); |
| 266 | Fput (intern ("downcase-region"), Qdisabled, Qt); | ||
| 267 | |||
| 265 | initial_define_key (meta_map, 'u', "upcase-word"); | 268 | initial_define_key (meta_map, 'u', "upcase-word"); |
| 266 | initial_define_key (meta_map, 'l', "downcase-word"); | 269 | initial_define_key (meta_map, 'l', "downcase-word"); |
| 267 | initial_define_key (meta_map, 'c', "capitalize-word"); | 270 | initial_define_key (meta_map, 'c', "capitalize-word"); |
diff --git a/src/casetab.c b/src/casetab.c index 6d419bfe30f..fa8375ccc69 100644 --- a/src/casetab.c +++ b/src/casetab.c | |||
| @@ -45,8 +45,8 @@ See `set-case-table' for more information on these data structures.") | |||
| 45 | (XTYPE (obj) == Lisp_String && XSTRING (obj)->size == 256) | 45 | (XTYPE (obj) == Lisp_String && XSTRING (obj)->size == 256) |
| 46 | 46 | ||
| 47 | return (STRING256_P (down) | 47 | return (STRING256_P (down) |
| 48 | && (NULL (up) || STRING256_P (up)) | 48 | && (NILP (up) || STRING256_P (up)) |
| 49 | && ((NULL (canon) && NULL (eqv)) | 49 | && ((NILP (canon) && NILP (eqv)) |
| 50 | || (STRING256_P (canon) && STRING256_P (eqv))) | 50 | || (STRING256_P (canon) && STRING256_P (eqv))) |
| 51 | ? Qt : Qnil); | 51 | ? Qt : Qnil); |
| 52 | } | 52 | } |
| @@ -57,7 +57,7 @@ check_case_table (obj) | |||
| 57 | { | 57 | { |
| 58 | register Lisp_Object tem; | 58 | register Lisp_Object tem; |
| 59 | 59 | ||
| 60 | while (tem = Fcase_table_p (obj), NULL (tem)) | 60 | while (tem = Fcase_table_p (obj), NILP (tem)) |
| 61 | obj = wrong_type_argument (Qcase_table_p, obj, 0); | 61 | obj = wrong_type_argument (Qcase_table_p, obj, 0); |
| 62 | return (obj); | 62 | return (obj); |
| 63 | } | 63 | } |
| @@ -132,13 +132,13 @@ set_case_table (table, standard) | |||
| 132 | canon = Fcar_safe (Fcdr_safe (Fcdr_safe (table))); | 132 | canon = Fcar_safe (Fcdr_safe (Fcdr_safe (table))); |
| 133 | eqv = Fcar_safe (Fcdr_safe (Fcdr_safe (Fcdr_safe (table)))); | 133 | eqv = Fcar_safe (Fcdr_safe (Fcdr_safe (Fcdr_safe (table)))); |
| 134 | 134 | ||
| 135 | if (NULL (up)) | 135 | if (NILP (up)) |
| 136 | { | 136 | { |
| 137 | up = Fmake_string (make_number (256), make_number (0)); | 137 | up = Fmake_string (make_number (256), make_number (0)); |
| 138 | compute_trt_inverse (XSTRING (down)->data, XSTRING (up)->data); | 138 | compute_trt_inverse (XSTRING (down)->data, XSTRING (up)->data); |
| 139 | } | 139 | } |
| 140 | 140 | ||
| 141 | if (NULL (canon)) | 141 | if (NILP (canon)) |
| 142 | { | 142 | { |
| 143 | register int i; | 143 | register int i; |
| 144 | unsigned char *upvec = XSTRING (up)->data; | 144 | unsigned char *upvec = XSTRING (up)->data; |
diff --git a/src/chpdef.h b/src/chpdef.h new file mode 100644 index 00000000000..43f7bbf4345 --- /dev/null +++ b/src/chpdef.h | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | #define CHP$_END 0 | ||
| 2 | #define CHP$_ACCESS 1 | ||
| 3 | #define CHP$_FLAGS 2 | ||
| 4 | #define CHP$_PRIV 3 | ||
| 5 | #define CHP$_ACMODE 4 | ||
| 6 | #define CHP$_ACCLASS 5 | ||
| 7 | #define CHP$_RIGHTS 6 | ||
| 8 | #define CHP$_ADDRIGHTS 7 | ||
| 9 | #define CHP$_MODE 8 | ||
| 10 | #define CHP$_MODES 9 | ||
| 11 | #define CHP$_MINCLASS 10 | ||
| 12 | #define CHP$_MAXCLASS 11 | ||
| 13 | #define CHP$_OWNER 12 | ||
| 14 | #define CHP$_PROT 13 | ||
| 15 | #define CHP$_ACL 14 | ||
| 16 | #define CHP$_AUDITNAME 15 | ||
| 17 | #define CHP$_ALARMNAME 16 | ||
| 18 | #define CHP$_MATCHEDACE 17 | ||
| 19 | #define CHP$_PRIVUSED 18 | ||
| 20 | #define CHP$_MAX_CODE 19 | ||
| 21 | #define CHP$M_SYSPRV 1 | ||
| 22 | #define CHP$M_BYPASS 2 | ||
| 23 | #define CHP$M_UPGRADE 4 | ||
| 24 | #define CHP$M_DOWNGRADE 8 | ||
| 25 | #define CHP$M_GRPPRV 16 | ||
| 26 | #define CHP$M_READALL 32 | ||
| 27 | #define CHP$V_SYSPRV 0 | ||
| 28 | #define CHP$V_BYPASS 1 | ||
| 29 | #define CHP$V_UPGRADE 2 | ||
| 30 | #define CHP$V_DOWNGRADE 3 | ||
| 31 | #define CHP$V_GRPPRV 4 | ||
| 32 | #define CHP$V_READALL 5 | ||
| 33 | #define CHP$M_READ 1 | ||
| 34 | #define CHP$M_WRITE 2 | ||
| 35 | #define CHP$M_USEREADALL 4 | ||
| 36 | #define CHP$V_READ 0 | ||
| 37 | #define CHP$V_WRITE 1 | ||
| 38 | #define CHP$V_USEREADALL 2 | ||
diff --git a/src/cm.c b/src/cm.c new file mode 100644 index 00000000000..f88acff48f1 --- /dev/null +++ b/src/cm.c | |||
| @@ -0,0 +1,414 @@ | |||
| 1 | /* Cursor motion subroutines for GNU Emacs. | ||
| 2 | Copyright (C) 1985 Free Software Foundation, Inc. | ||
| 3 | based primarily on public domain code written by Chris Torek | ||
| 4 | |||
| 5 | This file is part of GNU Emacs. | ||
| 6 | |||
| 7 | GNU Emacs is free software; you can redistribute it and/or modify | ||
| 8 | it under the terms of the GNU General Public License as published by | ||
| 9 | the Free Software Foundation; either version 1, or (at your option) | ||
| 10 | any later version. | ||
| 11 | |||
| 12 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | GNU General Public License for more details. | ||
| 16 | |||
| 17 | You should have received a copy of the GNU General Public License | ||
| 18 | along with GNU Emacs; see the file COPYING. If not, write to | ||
| 19 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
| 20 | |||
| 21 | |||
| 22 | #include "config.h" | ||
| 23 | #include <stdio.h> | ||
| 24 | #include "cm.h" | ||
| 25 | #include "termhooks.h" | ||
| 26 | |||
| 27 | #define BIG 9999 /* 9999 good on VAXen. For 16 bit machines | ||
| 28 | use about 2000.... */ | ||
| 29 | |||
| 30 | char *tgoto (); | ||
| 31 | |||
| 32 | extern char *BC, *UP; | ||
| 33 | |||
| 34 | int cost; /* sums up costs */ | ||
| 35 | |||
| 36 | /* ARGSUSED */ | ||
| 37 | evalcost (c) | ||
| 38 | char c; | ||
| 39 | { | ||
| 40 | cost++; | ||
| 41 | } | ||
| 42 | |||
| 43 | void | ||
| 44 | cmputc (c) | ||
| 45 | char c; | ||
| 46 | { | ||
| 47 | if (termscript) | ||
| 48 | fputc (c & 0177, termscript); | ||
| 49 | putchar (c & 0177); | ||
| 50 | } | ||
| 51 | |||
| 52 | /* NEXT TWO ARE DONE WITH MACROS */ | ||
| 53 | #if 0 | ||
| 54 | /* | ||
| 55 | * Assume the cursor is at row row, column col. Normally used only after | ||
| 56 | * clearing the screen, when the cursor is at (0, 0), but what the heck, | ||
| 57 | * let's let the guy put it anywhere. | ||
| 58 | */ | ||
| 59 | |||
| 60 | static | ||
| 61 | at (row, col) { | ||
| 62 | curY = row; | ||
| 63 | curX = col; | ||
| 64 | } | ||
| 65 | |||
| 66 | /* | ||
| 67 | * Add n columns to the current cursor position. | ||
| 68 | */ | ||
| 69 | |||
| 70 | static | ||
| 71 | addcol (n) { | ||
| 72 | curX += n; | ||
| 73 | |||
| 74 | /* | ||
| 75 | * If cursor hit edge of screen, what happened? | ||
| 76 | * N.B.: DO NOT!! write past edge of screen. If you do, you | ||
| 77 | * deserve what you get. Furthermore, on terminals with | ||
| 78 | * autowrap (but not magicwrap), don't write in the last column | ||
| 79 | * of the last line. | ||
| 80 | */ | ||
| 81 | |||
| 82 | if (curX == Wcm.cm_cols) { | ||
| 83 | /* | ||
| 84 | * Well, if magicwrap, still there, past the edge of the | ||
| 85 | * screen (!). If autowrap, on the col 0 of the next line. | ||
| 86 | * Otherwise on last column. | ||
| 87 | */ | ||
| 88 | |||
| 89 | if (Wcm.cm_magicwrap) | ||
| 90 | ; /* "limbo" */ | ||
| 91 | else if (Wcm.cm_autowrap) { | ||
| 92 | curX = 0; | ||
| 93 | curY++; /* Beware end of screen! */ | ||
| 94 | } | ||
| 95 | else | ||
| 96 | curX--; | ||
| 97 | } | ||
| 98 | } | ||
| 99 | #endif | ||
| 100 | |||
| 101 | /* | ||
| 102 | * (Re)Initialize the cost factors, given the output speed of the terminal | ||
| 103 | * in the variable ospeed. (Note: this holds B300, B9600, etc -- ie stuff | ||
| 104 | * out of <sgtty.h>.) | ||
| 105 | */ | ||
| 106 | |||
| 107 | cmcostinit () | ||
| 108 | { | ||
| 109 | char *p; | ||
| 110 | |||
| 111 | #define COST(x,e) (x ? (cost = 0, tputs (x, 1, e), cost) : BIG) | ||
| 112 | #define CMCOST(x,e) ((x == 0) ? BIG : (p = tgoto(x, 0, 0), COST(p ,e))) | ||
| 113 | |||
| 114 | Wcm.cc_up = COST (Wcm.cm_up, evalcost); | ||
| 115 | Wcm.cc_down = COST (Wcm.cm_down, evalcost); | ||
| 116 | Wcm.cc_left = COST (Wcm.cm_left, evalcost); | ||
| 117 | Wcm.cc_right = COST (Wcm.cm_right, evalcost); | ||
| 118 | Wcm.cc_home = COST (Wcm.cm_home, evalcost); | ||
| 119 | Wcm.cc_cr = COST (Wcm.cm_cr, evalcost); | ||
| 120 | Wcm.cc_ll = COST (Wcm.cm_ll, evalcost); | ||
| 121 | Wcm.cc_tab = Wcm.cm_tabwidth ? COST (Wcm.cm_tab, evalcost) : BIG; | ||
| 122 | |||
| 123 | /* | ||
| 124 | * These last three are actually minimum costs. When (if) they are | ||
| 125 | * candidates for the least-cost motion, the real cost is computed. | ||
| 126 | * (Note that "0" is the assumed to generate the minimum cost. | ||
| 127 | * While this is not necessarily true, I have yet to see a terminal | ||
| 128 | * for which is not; all the terminals that have variable-cost | ||
| 129 | * cursor motion seem to take straight numeric values. --ACT) | ||
| 130 | */ | ||
| 131 | |||
| 132 | Wcm.cc_abs = CMCOST (Wcm.cm_abs, evalcost); | ||
| 133 | Wcm.cc_habs = CMCOST (Wcm.cm_habs, evalcost); | ||
| 134 | Wcm.cc_vabs = CMCOST (Wcm.cm_vabs, evalcost); | ||
| 135 | |||
| 136 | #undef CMCOST | ||
| 137 | #undef COST | ||
| 138 | } | ||
| 139 | |||
| 140 | /* | ||
| 141 | * Calculate the cost to move from (srcy, srcx) to (dsty, dstx) using | ||
| 142 | * up and down, and left and right, motions, and tabs. If doit is set | ||
| 143 | * actually perform the motion. | ||
| 144 | */ | ||
| 145 | |||
| 146 | static | ||
| 147 | calccost (srcy, srcx, dsty, dstx, doit) | ||
| 148 | { | ||
| 149 | register int deltay, | ||
| 150 | deltax, | ||
| 151 | c, | ||
| 152 | totalcost; | ||
| 153 | int ntabs, | ||
| 154 | n2tabs, | ||
| 155 | tabx, | ||
| 156 | tab2x, | ||
| 157 | tabcost; | ||
| 158 | register char *p; | ||
| 159 | |||
| 160 | /* If have just wrapped on a terminal with xn, | ||
| 161 | don't believe the cursor position: give up here | ||
| 162 | and force use of absolute positioning. */ | ||
| 163 | |||
| 164 | if (curX == Wcm.cm_cols) | ||
| 165 | goto fail; | ||
| 166 | |||
| 167 | totalcost = 0; | ||
| 168 | if ((deltay = dsty - srcy) == 0) | ||
| 169 | goto x; | ||
| 170 | if (deltay < 0) | ||
| 171 | p = Wcm.cm_up, c = Wcm.cc_up, deltay = -deltay; | ||
| 172 | else | ||
| 173 | p = Wcm.cm_down, c = Wcm.cc_down; | ||
| 174 | if (c == BIG) { /* caint get thar from here */ | ||
| 175 | if (doit) | ||
| 176 | printf ("OOPS"); | ||
| 177 | return c; | ||
| 178 | } | ||
| 179 | totalcost = c * deltay; | ||
| 180 | if (doit) | ||
| 181 | while (--deltay >= 0) | ||
| 182 | tputs (p, 1, cmputc); | ||
| 183 | x: | ||
| 184 | if ((deltax = dstx - srcx) == 0) | ||
| 185 | goto done; | ||
| 186 | if (deltax < 0) { | ||
| 187 | p = Wcm.cm_left, c = Wcm.cc_left, deltax = -deltax; | ||
| 188 | goto dodelta; /* skip all the tab junk */ | ||
| 189 | } | ||
| 190 | /* Tabs (the toughie) */ | ||
| 191 | if (Wcm.cc_tab >= BIG || !Wcm.cm_usetabs) | ||
| 192 | goto olddelta; /* forget it! */ | ||
| 193 | |||
| 194 | /* | ||
| 195 | * ntabs is # tabs towards but not past dstx; n2tabs is one more | ||
| 196 | * (ie past dstx), but this is only valid if that is not past the | ||
| 197 | * right edge of the screen. We can check that at the same time | ||
| 198 | * as we figure out where we would be if we use the tabs (which | ||
| 199 | * we will put into tabx (for ntabs) and tab2x (for n2tabs)). | ||
| 200 | */ | ||
| 201 | |||
| 202 | ntabs = (deltax + srcx % Wcm.cm_tabwidth) / Wcm.cm_tabwidth; | ||
| 203 | n2tabs = ntabs + 1; | ||
| 204 | tabx = (srcx / Wcm.cm_tabwidth + ntabs) * Wcm.cm_tabwidth; | ||
| 205 | tab2x = tabx + Wcm.cm_tabwidth; | ||
| 206 | |||
| 207 | if (tab2x >= Wcm.cm_cols) /* too far (past edge) */ | ||
| 208 | n2tabs = 0; | ||
| 209 | |||
| 210 | /* | ||
| 211 | * Now set tabcost to the cost for using ntabs, and c to the cost | ||
| 212 | * for using n2tabs, then pick the minimum. | ||
| 213 | */ | ||
| 214 | |||
| 215 | /* cost for ntabs + cost for right motion */ | ||
| 216 | tabcost = ntabs ? ntabs * Wcm.cc_tab + (dstx - tabx) * Wcm.cc_right | ||
| 217 | : BIG; | ||
| 218 | |||
| 219 | /* cost for n2tabs + cost for left motion */ | ||
| 220 | c = n2tabs ? n2tabs * Wcm.cc_tab + (tab2x - dstx) * Wcm.cc_left | ||
| 221 | : BIG; | ||
| 222 | |||
| 223 | if (c < tabcost) /* then cheaper to overshoot & back up */ | ||
| 224 | ntabs = n2tabs, tabcost = c, tabx = tab2x; | ||
| 225 | |||
| 226 | if (tabcost >= BIG) /* caint use tabs */ | ||
| 227 | goto newdelta; | ||
| 228 | |||
| 229 | /* | ||
| 230 | * See if tabcost is less than just moving right | ||
| 231 | */ | ||
| 232 | |||
| 233 | if (tabcost < (deltax * Wcm.cc_right)) { | ||
| 234 | totalcost += tabcost; /* use the tabs */ | ||
| 235 | if (doit) | ||
| 236 | while (--ntabs >= 0) | ||
| 237 | tputs (Wcm.cm_tab, 1, cmputc); | ||
| 238 | srcx = tabx; | ||
| 239 | } | ||
| 240 | |||
| 241 | /* | ||
| 242 | * Now might as well just recompute the delta. | ||
| 243 | */ | ||
| 244 | |||
| 245 | newdelta: | ||
| 246 | if ((deltax = dstx - srcx) == 0) | ||
| 247 | goto done; | ||
| 248 | olddelta: | ||
| 249 | if (deltax > 0) | ||
| 250 | p = Wcm.cm_right, c = Wcm.cc_right; | ||
| 251 | else | ||
| 252 | p = Wcm.cm_left, c = Wcm.cc_left, deltax = -deltax; | ||
| 253 | |||
| 254 | dodelta: | ||
| 255 | if (c == BIG) { /* caint get thar from here */ | ||
| 256 | fail: | ||
| 257 | if (doit) | ||
| 258 | printf ("OOPS"); | ||
| 259 | return BIG; | ||
| 260 | } | ||
| 261 | totalcost += c * deltax; | ||
| 262 | if (doit) | ||
| 263 | while (--deltax >= 0) | ||
| 264 | tputs (p, 1, cmputc); | ||
| 265 | done: | ||
| 266 | return totalcost; | ||
| 267 | } | ||
| 268 | |||
| 269 | #if 0 | ||
| 270 | losecursor () | ||
| 271 | { | ||
| 272 | curY = -1; | ||
| 273 | } | ||
| 274 | #endif | ||
| 275 | |||
| 276 | #define USEREL 0 | ||
| 277 | #define USEHOME 1 | ||
| 278 | #define USELL 2 | ||
| 279 | #define USECR 3 | ||
| 280 | |||
| 281 | cmgoto (row, col) | ||
| 282 | { | ||
| 283 | int homecost, | ||
| 284 | crcost, | ||
| 285 | llcost, | ||
| 286 | relcost, | ||
| 287 | directcost; | ||
| 288 | int use; | ||
| 289 | char *p, | ||
| 290 | *dcm; | ||
| 291 | |||
| 292 | /* First the degenerate case */ | ||
| 293 | if (row == curY && col == curX) /* already there */ | ||
| 294 | return; | ||
| 295 | |||
| 296 | if (curY >= 0 && curX >= 0) | ||
| 297 | { | ||
| 298 | /* We may have quick ways to go to the upper-left, bottom-left, | ||
| 299 | * start-of-line, or start-of-next-line. Or it might be best to | ||
| 300 | * start where we are. Examine the options, and pick the cheapest. | ||
| 301 | */ | ||
| 302 | |||
| 303 | relcost = calccost (curY, curX, row, col, 0); | ||
| 304 | use = USEREL; | ||
| 305 | if ((homecost = Wcm.cc_home) < BIG) | ||
| 306 | homecost += calccost (0, 0, row, col, 0); | ||
| 307 | if (homecost < relcost) | ||
| 308 | relcost = homecost, use = USEHOME; | ||
| 309 | if ((llcost = Wcm.cc_ll) < BIG) | ||
| 310 | llcost += calccost (Wcm.cm_rows - 1, 0, row, col, 0); | ||
| 311 | if (llcost < relcost) | ||
| 312 | relcost = llcost, use = USELL; | ||
| 313 | if ((crcost = Wcm.cc_cr) < BIG) { | ||
| 314 | if (Wcm.cm_autolf) | ||
| 315 | if (curY + 1 >= Wcm.cm_rows) | ||
| 316 | crcost = BIG; | ||
| 317 | else | ||
| 318 | crcost += calccost (curY + 1, 0, row, col, 0); | ||
| 319 | else | ||
| 320 | crcost += calccost (curY, 0, row, col, 0); | ||
| 321 | } | ||
| 322 | if (crcost < relcost) | ||
| 323 | relcost = crcost, use = USECR; | ||
| 324 | directcost = Wcm.cc_abs, dcm = Wcm.cm_abs; | ||
| 325 | if (row == curY && Wcm.cc_habs < BIG) | ||
| 326 | directcost = Wcm.cc_habs, dcm = Wcm.cm_habs; | ||
| 327 | else if (col == curX && Wcm.cc_vabs < BIG) | ||
| 328 | directcost = Wcm.cc_vabs, dcm = Wcm.cm_vabs; | ||
| 329 | } | ||
| 330 | else | ||
| 331 | { | ||
| 332 | directcost = 0, relcost = 100000; | ||
| 333 | dcm = Wcm.cm_abs; | ||
| 334 | } | ||
| 335 | |||
| 336 | /* | ||
| 337 | * In the following comparison, the = in <= is because when the costs | ||
| 338 | * are the same, it looks nicer (I think) to move directly there. | ||
| 339 | */ | ||
| 340 | if (directcost <= relcost) | ||
| 341 | { | ||
| 342 | /* compute REAL direct cost */ | ||
| 343 | cost = 0; | ||
| 344 | p = dcm == Wcm.cm_habs ? tgoto (dcm, row, col) : | ||
| 345 | tgoto (dcm, col, row); | ||
| 346 | tputs (p, 1, evalcost); | ||
| 347 | if (cost <= relcost) | ||
| 348 | { /* really is cheaper */ | ||
| 349 | tputs (p, 1, cmputc); | ||
| 350 | curY = row, curX = col; | ||
| 351 | return; | ||
| 352 | } | ||
| 353 | } | ||
| 354 | |||
| 355 | switch (use) | ||
| 356 | { | ||
| 357 | case USEHOME: | ||
| 358 | tputs (Wcm.cm_home, 1, cmputc); | ||
| 359 | curY = 0, curX = 0; | ||
| 360 | break; | ||
| 361 | |||
| 362 | case USELL: | ||
| 363 | tputs (Wcm.cm_ll, 1, cmputc); | ||
| 364 | curY = Wcm.cm_rows - 1, curX = 0; | ||
| 365 | break; | ||
| 366 | |||
| 367 | case USECR: | ||
| 368 | tputs (Wcm.cm_cr, 1, cmputc); | ||
| 369 | if (Wcm.cm_autolf) | ||
| 370 | curY++; | ||
| 371 | curX = 0; | ||
| 372 | break; | ||
| 373 | } | ||
| 374 | |||
| 375 | (void) calccost (curY, curX, row, col, 1); | ||
| 376 | curY = row, curX = col; | ||
| 377 | } | ||
| 378 | |||
| 379 | /* Clear out all terminal info. | ||
| 380 | Used before copying into it the info on the actual terminal. | ||
| 381 | */ | ||
| 382 | |||
| 383 | Wcm_clear () | ||
| 384 | { | ||
| 385 | bzero (&Wcm, sizeof Wcm); | ||
| 386 | UP = 0; | ||
| 387 | BC = 0; | ||
| 388 | } | ||
| 389 | |||
| 390 | /* | ||
| 391 | * Initialized stuff | ||
| 392 | * Return 0 if can do CM. | ||
| 393 | * Return -1 if cannot. | ||
| 394 | * Return -2 if size not specified. | ||
| 395 | */ | ||
| 396 | |||
| 397 | Wcm_init () | ||
| 398 | { | ||
| 399 | #if 0 | ||
| 400 | if (Wcm.cm_abs && !Wcm.cm_ds) | ||
| 401 | return 0; | ||
| 402 | #endif | ||
| 403 | if (Wcm.cm_abs) | ||
| 404 | return 0; | ||
| 405 | /* Require up and left, and, if no absolute, down and right */ | ||
| 406 | if (!Wcm.cm_up || !Wcm.cm_left) | ||
| 407 | return - 1; | ||
| 408 | if (!Wcm.cm_abs && (!Wcm.cm_down || !Wcm.cm_right)) | ||
| 409 | return - 1; | ||
| 410 | /* Check that we know the size of the screen.... */ | ||
| 411 | if (Wcm.cm_rows <= 0 || Wcm.cm_cols <= 0) | ||
| 412 | return - 2; | ||
| 413 | return 0; | ||
| 414 | } | ||
diff --git a/src/disptab.h b/src/disptab.h new file mode 100644 index 00000000000..67d36195555 --- /dev/null +++ b/src/disptab.h | |||
| @@ -0,0 +1,82 @@ | |||
| 1 | /* Things for GLYPHS and glyph tables. | ||
| 2 | Copyright (C) 1990 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is part of GNU Emacs. | ||
| 5 | |||
| 6 | GNU Emacs is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 1, or (at your option) | ||
| 9 | any later version. | ||
| 10 | |||
| 11 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with GNU Emacs; see the file COPYING. If not, write to | ||
| 18 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
| 19 | |||
| 20 | /* Access the slots of a display-table, according to their purpose. */ | ||
| 21 | |||
| 22 | #define DISP_TABLE_SIZE 261 | ||
| 23 | #define DISP_TRUNC_GLYPH(dp) ((dp)->contents[256]) | ||
| 24 | #define DISP_CONTINUE_GLYPH(dp) ((dp)->contents[257]) | ||
| 25 | #define DISP_ESCAPE_GLYPH(dp) ((dp)->contents[258]) | ||
| 26 | #define DISP_CTRL_GLYPH(dp) ((dp)->contents[259]) | ||
| 27 | #define DISP_INVIS_ROPE(dp) ((dp)->contents[260]) | ||
| 28 | #define DISP_CHAR_ROPE(dp, c) ((dp)->contents[c]) | ||
| 29 | |||
| 30 | extern struct Lisp_Vector *window_display_table (); | ||
| 31 | |||
| 32 | /* Display table to use for vectors that don't specify their own. */ | ||
| 33 | extern Lisp_Object Vstandard_display_table; | ||
| 34 | |||
| 35 | /* Vector of GLYPH definitions. Indexed by GLYPH number, | ||
| 36 | the contents are a string which is how to output the GLYPH. */ | ||
| 37 | extern Lisp_Object Vglyph_table; | ||
| 38 | |||
| 39 | /* Return the current length of the GLYPH table, | ||
| 40 | or 0 if the table isn't currently valid. */ | ||
| 41 | #define GLYPH_TABLE_LENGTH \ | ||
| 42 | ((XTYPE (Vglyph_table) == Lisp_Vector) \ | ||
| 43 | ? XVECTOR (Vglyph_table)->size : 0) | ||
| 44 | |||
| 45 | /* Return the current base (for indexing) of the GLYPH table, | ||
| 46 | or 0 if the table isn't currently valid. */ | ||
| 47 | #define GLYPH_TABLE_BASE \ | ||
| 48 | ((XTYPE (Vglyph_table) == Lisp_Vector) \ | ||
| 49 | ? XVECTOR (Vglyph_table)->contents : 0) | ||
| 50 | |||
| 51 | /* Given BASE and LEN returned by the two previous macros, | ||
| 52 | return nonzero if the GLYPH code G should be output as a single | ||
| 53 | character with code G. Return zero if G has a string in the table. */ | ||
| 54 | #define GLYPH_SIMPLE_P(base,len,g) \ | ||
| 55 | ((g) >= (len) || XTYPE (base[g]) != Lisp_String) | ||
| 56 | |||
| 57 | /* Given BASE and LEN returned by the two previous macros, | ||
| 58 | return nonzero if GLYPH code G is aliased to a different code. */ | ||
| 59 | #define GLYPH_ALIAS_P(base,len,g) \ | ||
| 60 | ((g) < (len) && XTYPE (base[g]) == Lisp_Int) | ||
| 61 | |||
| 62 | /* Assuming that GLYPH_SIMPLE_P (BASE, LEN, G) is 1, | ||
| 63 | return the alias for G. */ | ||
| 64 | #define GLYPH_ALIAS(base, g) XINT (base[g]) | ||
| 65 | |||
| 66 | /* Assuming that GLYPH_SIMPLE_P (BASE, LEN, G) is 0, | ||
| 67 | return the length and the address of the character-sequence | ||
| 68 | used for outputting GLYPH G. */ | ||
| 69 | #define GLYPH_LENGTH(base,g) XSTRING (base[g])->size | ||
| 70 | #define GLYPH_STRING(base,g) XSTRING (base[g])->data | ||
| 71 | |||
| 72 | /* GLYPH for a space character. */ | ||
| 73 | |||
| 74 | #define SPACEGLYPH 040 | ||
| 75 | #define NULL_GLYPH 00 | ||
| 76 | |||
| 77 | #define GLYPH_FROM_CHAR(c) (c) | ||
| 78 | |||
| 79 | extern int glyphlen (); | ||
| 80 | extern void str_to_glyph_cpy (); | ||
| 81 | extern void str_to_glyph_ncpy (); | ||
| 82 | extern void glyph_to_str_cpy (); | ||
diff --git a/src/doprnt.c b/src/doprnt.c index 731afe400cc..02584554577 100644 --- a/src/doprnt.c +++ b/src/doprnt.c | |||
| @@ -68,10 +68,10 @@ doprnt (buffer, bufsize, format, format_end, nargs, args) | |||
| 68 | int size_bound; | 68 | int size_bound; |
| 69 | 69 | ||
| 70 | fmt++; | 70 | fmt++; |
| 71 | /* Copy this one %-spec into fmtcopy. */ | 71 | /* Copy this one %-spec into fmtcpy. */ |
| 72 | string = fmtcpy; | 72 | string = fmtcpy; |
| 73 | *string++ = '%'; | 73 | *string++ = '%'; |
| 74 | while (1) | 74 | while (string < fmtcpy + sizeof fmtcpy - 1) |
| 75 | { | 75 | { |
| 76 | *string++ = *fmt; | 76 | *string++ = *fmt; |
| 77 | if (! (*fmt >= '0' && *fmt <= '9') && *fmt != '-' && *fmt != ' ') | 77 | if (! (*fmt >= '0' && *fmt <= '9') && *fmt != '-' && *fmt != ' ') |
diff --git a/src/indent.h b/src/indent.h new file mode 100644 index 00000000000..ec6dcaeadf0 --- /dev/null +++ b/src/indent.h | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | /* Definitions for interface to indent.c | ||
| 2 | Copyright (C) 1985, 1986 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is part of GNU Emacs. | ||
| 5 | |||
| 6 | GNU Emacs is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 1, or (at your option) | ||
| 9 | any later version. | ||
| 10 | |||
| 11 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with GNU Emacs; see the file COPYING. If not, write to | ||
| 18 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
| 19 | |||
| 20 | |||
| 21 | struct position | ||
| 22 | { | ||
| 23 | int bufpos; | ||
| 24 | int hpos; | ||
| 25 | int vpos; | ||
| 26 | int prevhpos; | ||
| 27 | int contin; | ||
| 28 | }; | ||
| 29 | |||
| 30 | struct position *compute_motion (); | ||
| 31 | struct position *vmotion (); | ||
| 32 | |||
| 33 | /* Value of point when current_column was called */ | ||
| 34 | extern int last_known_column_point; | ||
diff --git a/src/insdel.c b/src/insdel.c index 80f1d67369b..1deda9d7ac8 100644 --- a/src/insdel.c +++ b/src/insdel.c | |||
| @@ -214,7 +214,7 @@ adjust_markers (from, to, amount) | |||
| 214 | 214 | ||
| 215 | marker = current_buffer->markers; | 215 | marker = current_buffer->markers; |
| 216 | 216 | ||
| 217 | while (!NULL (marker)) | 217 | while (!NILP (marker)) |
| 218 | { | 218 | { |
| 219 | m = XMARKER (marker); | 219 | m = XMARKER (marker); |
| 220 | mpos = m->bufpos; | 220 | mpos = m->bufpos; |
| @@ -352,7 +352,7 @@ insert_from_string (string, pos, length) | |||
| 352 | GPT += length; | 352 | GPT += length; |
| 353 | ZV += length; | 353 | ZV += length; |
| 354 | Z += length; | 354 | Z += length; |
| 355 | point += length; | 355 | SET_PT (point + length); |
| 356 | 356 | ||
| 357 | signal_after_change (point-length, 0, length); | 357 | signal_after_change (point-length, 0, length); |
| 358 | } | 358 | } |
| @@ -473,22 +473,22 @@ modify_region (start, end) | |||
| 473 | prepare_to_modify_buffer (start, end) | 473 | prepare_to_modify_buffer (start, end) |
| 474 | Lisp_Object start, end; | 474 | Lisp_Object start, end; |
| 475 | { | 475 | { |
| 476 | if (!NULL (current_buffer->read_only)) | 476 | if (!NILP (current_buffer->read_only)) |
| 477 | Fbarf_if_buffer_read_only (); | 477 | Fbarf_if_buffer_read_only (); |
| 478 | 478 | ||
| 479 | if (check_protected_fields) | 479 | if (check_protected_fields) |
| 480 | Fregion_fields (start, end, Qnil, Qt); | 480 | Fregion_fields (start, end, Qnil, Qt); |
| 481 | 481 | ||
| 482 | #ifdef CLASH_DETECTION | 482 | #ifdef CLASH_DETECTION |
| 483 | if (!NULL (current_buffer->filename) | 483 | if (!NILP (current_buffer->filename) |
| 484 | && current_buffer->save_modified >= MODIFF) | 484 | && current_buffer->save_modified >= MODIFF) |
| 485 | lock_file (current_buffer->filename); | 485 | lock_file (current_buffer->filename); |
| 486 | #else | 486 | #else |
| 487 | /* At least warn if this file has changed on disk since it was visited. */ | 487 | /* At least warn if this file has changed on disk since it was visited. */ |
| 488 | if (!NULL (current_buffer->filename) | 488 | if (!NILP (current_buffer->filename) |
| 489 | && current_buffer->save_modified >= MODIFF | 489 | && current_buffer->save_modified >= MODIFF |
| 490 | && NULL (Fverify_visited_file_modtime (Fcurrent_buffer ())) | 490 | && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ())) |
| 491 | && !NULL (Ffile_exists_p (current_buffer->filename))) | 491 | && !NILP (Ffile_exists_p (current_buffer->filename))) |
| 492 | call1 (intern ("ask-user-about-supersession-threat"), | 492 | call1 (intern ("ask-user-about-supersession-threat"), |
| 493 | current_buffer->filename); | 493 | current_buffer->filename); |
| 494 | #endif /* not CLASH_DETECTION */ | 494 | #endif /* not CLASH_DETECTION */ |
| @@ -519,12 +519,12 @@ signal_before_change (start, end) | |||
| 519 | { | 519 | { |
| 520 | /* If buffer is unmodified, run a special hook for that case. */ | 520 | /* If buffer is unmodified, run a special hook for that case. */ |
| 521 | if (current_buffer->save_modified >= MODIFF | 521 | if (current_buffer->save_modified >= MODIFF |
| 522 | && !NULL (Vfirst_change_function)) | 522 | && !NILP (Vfirst_change_function)) |
| 523 | { | 523 | { |
| 524 | call0 (Vfirst_change_function); | 524 | call0 (Vfirst_change_function); |
| 525 | } | 525 | } |
| 526 | /* Now in any case run the before-change-function if any. */ | 526 | /* Now in any case run the before-change-function if any. */ |
| 527 | if (!NULL (Vbefore_change_function)) | 527 | if (!NILP (Vbefore_change_function)) |
| 528 | { | 528 | { |
| 529 | int count = specpdl_ptr - specpdl; | 529 | int count = specpdl_ptr - specpdl; |
| 530 | Lisp_Object function; | 530 | Lisp_Object function; |
| @@ -551,7 +551,7 @@ signal_before_change (start, end) | |||
| 551 | signal_after_change (pos, lendel, lenins) | 551 | signal_after_change (pos, lendel, lenins) |
| 552 | int pos, lendel, lenins; | 552 | int pos, lendel, lenins; |
| 553 | { | 553 | { |
| 554 | if (!NULL (Vafter_change_function)) | 554 | if (!NILP (Vafter_change_function)) |
| 555 | { | 555 | { |
| 556 | int count = specpdl_ptr - specpdl; | 556 | int count = specpdl_ptr - specpdl; |
| 557 | Lisp_Object function; | 557 | Lisp_Object function; |
diff --git a/src/ioctl.h b/src/ioctl.h new file mode 100644 index 00000000000..0366f6d6bd5 --- /dev/null +++ b/src/ioctl.h | |||
| @@ -0,0 +1 @@ | |||
| /* Emacs ioctl emulation for VMS */ | |||
diff --git a/src/lastfile.c b/src/lastfile.c new file mode 100644 index 00000000000..6588a593c92 --- /dev/null +++ b/src/lastfile.c | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | /* Mark end of data space to dump as pure, for GNU Emacs. | ||
| 2 | Copyright (C) 1985 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is part of GNU Emacs. | ||
| 5 | |||
| 6 | GNU Emacs is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 1, or (at your option) | ||
| 9 | any later version. | ||
| 10 | |||
| 11 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with GNU Emacs; see the file COPYING. If not, write to | ||
| 18 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
| 19 | |||
| 20 | |||
| 21 | /* How this works: | ||
| 22 | |||
| 23 | Fdump_emacs dumps everything up to my_edata as text space (pure). | ||
| 24 | |||
| 25 | The files of Emacs are written so as to have no initialized | ||
| 26 | data that can ever need to be altered except at the first startup. | ||
| 27 | This is so that those words can be dumped as sharable text. | ||
| 28 | |||
| 29 | It is not possible to exercise such control over library files. | ||
| 30 | So it is necessary to refrain from making their data areas shared. | ||
| 31 | Therefore, this file is loaded following all the files of Emacs | ||
| 32 | but before library files. | ||
| 33 | As a result, the symbol my_edata indicates the point | ||
| 34 | in data space between data coming from Emacs and data | ||
| 35 | coming from libraries. | ||
| 36 | */ | ||
| 37 | |||
| 38 | char my_edata = 0; | ||
diff --git a/src/line.h b/src/line.h new file mode 100644 index 00000000000..e3441aaaa93 --- /dev/null +++ b/src/line.h | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | #define line_width 30 | ||
| 2 | #define line_height 10 | ||
| 3 | static char line_bits[] = { | ||
| 4 | 0xf0, 0xff, 0xff, 0x03, 0x08, 0x00, 0x00, 0x04, 0x44, 0x48, 0xf4, 0x08, | ||
| 5 | 0x42, 0xc8, 0x14, 0x10, 0x41, 0x48, 0x75, 0x20, 0x41, 0x48, 0x15, 0x20, | ||
| 6 | 0x42, 0x48, 0x16, 0x10, 0xc4, 0x4b, 0xf4, 0x08, 0x08, 0x00, 0x00, 0x04, | ||
| 7 | 0xf0, 0xff, 0xff, 0x03}; | ||
diff --git a/src/macros.h b/src/macros.h new file mode 100644 index 00000000000..36d66898c46 --- /dev/null +++ b/src/macros.h | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | /* Definitions for keyboard macro interpretation in GNU Emacs. | ||
| 2 | Copyright (C) 1985 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is part of GNU Emacs. | ||
| 5 | |||
| 6 | GNU Emacs is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 1, or (at your option) | ||
| 9 | any later version. | ||
| 10 | |||
| 11 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with GNU Emacs; see the file COPYING. If not, write to | ||
| 18 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
| 19 | |||
| 20 | |||
| 21 | /* Kbd macro currently being executed (a string) */ | ||
| 22 | |||
| 23 | extern Lisp_Object Vexecuting_macro; | ||
| 24 | |||
| 25 | /* Index of next character to fetch from that macro */ | ||
| 26 | |||
| 27 | extern int executing_macro_index; | ||
| 28 | |||
| 29 | /* Nonzero while defining a kbd macro */ | ||
| 30 | |||
| 31 | extern int defining_kbd_macro; | ||
diff --git a/src/marker.c b/src/marker.c index d8c0a89819a..6c26e72fae4 100644 --- a/src/marker.c +++ b/src/marker.c | |||
| @@ -36,7 +36,7 @@ Returns nil if MARKER points into a dead buffer.") | |||
| 36 | { | 36 | { |
| 37 | XSET (buf, Lisp_Buffer, XMARKER (marker)->buffer); | 37 | XSET (buf, Lisp_Buffer, XMARKER (marker)->buffer); |
| 38 | /* Return marker's buffer only if it is not dead. */ | 38 | /* Return marker's buffer only if it is not dead. */ |
| 39 | if (!NULL (XBUFFER (buf)->name)) | 39 | if (!NILP (XBUFFER (buf)->name)) |
| 40 | return buf; | 40 | return buf; |
| 41 | } | 41 | } |
| 42 | return Qnil; | 42 | return Qnil; |
| @@ -87,7 +87,7 @@ Returns MARKER.") | |||
| 87 | CHECK_MARKER (marker, 0); | 87 | CHECK_MARKER (marker, 0); |
| 88 | /* If position is nil or a marker that points nowhere, | 88 | /* If position is nil or a marker that points nowhere, |
| 89 | make this marker point nowhere. */ | 89 | make this marker point nowhere. */ |
| 90 | if (NULL (pos) | 90 | if (NILP (pos) |
| 91 | || (XTYPE (pos) == Lisp_Marker && !XMARKER (pos)->buffer)) | 91 | || (XTYPE (pos) == Lisp_Marker && !XMARKER (pos)->buffer)) |
| 92 | { | 92 | { |
| 93 | unchain_marker (marker); | 93 | unchain_marker (marker); |
| @@ -95,7 +95,7 @@ Returns MARKER.") | |||
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | CHECK_NUMBER_COERCE_MARKER (pos, 1); | 97 | CHECK_NUMBER_COERCE_MARKER (pos, 1); |
| 98 | if (NULL (buffer)) | 98 | if (NILP (buffer)) |
| 99 | b = current_buffer; | 99 | b = current_buffer; |
| 100 | else | 100 | else |
| 101 | { | 101 | { |
| @@ -144,7 +144,7 @@ set_marker_restricted (marker, pos, buffer) | |||
| 144 | CHECK_MARKER (marker, 0); | 144 | CHECK_MARKER (marker, 0); |
| 145 | /* If position is nil or a marker that points nowhere, | 145 | /* If position is nil or a marker that points nowhere, |
| 146 | make this marker point nowhere. */ | 146 | make this marker point nowhere. */ |
| 147 | if (NULL (pos) || | 147 | if (NILP (pos) || |
| 148 | (XTYPE (pos) == Lisp_Marker && !XMARKER (pos)->buffer)) | 148 | (XTYPE (pos) == Lisp_Marker && !XMARKER (pos)->buffer)) |
| 149 | { | 149 | { |
| 150 | unchain_marker (marker); | 150 | unchain_marker (marker); |
| @@ -152,7 +152,7 @@ set_marker_restricted (marker, pos, buffer) | |||
| 152 | } | 152 | } |
| 153 | 153 | ||
| 154 | CHECK_NUMBER_COERCE_MARKER (pos, 1); | 154 | CHECK_NUMBER_COERCE_MARKER (pos, 1); |
| 155 | if (NULL (buffer)) | 155 | if (NILP (buffer)) |
| 156 | b = current_buffer; | 156 | b = current_buffer; |
| 157 | else | 157 | else |
| 158 | { | 158 | { |
| @@ -215,7 +215,7 @@ unchain_marker (marker) | |||
| 215 | 215 | ||
| 216 | if (XMARKER (marker) == XMARKER (tail)) | 216 | if (XMARKER (marker) == XMARKER (tail)) |
| 217 | { | 217 | { |
| 218 | if (NULL (prev)) | 218 | if (NILP (prev)) |
| 219 | { | 219 | { |
| 220 | b->markers = next; | 220 | b->markers = next; |
| 221 | /* Deleting first marker from the buffer's chain. | 221 | /* Deleting first marker from the buffer's chain. |
diff --git a/src/mocklisp.c b/src/mocklisp.c index 5f0800f94c1..353d4da0e43 100644 --- a/src/mocklisp.c +++ b/src/mocklisp.c | |||
| @@ -32,7 +32,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |||
| 32 | * { | 32 | * { |
| 33 | * Lisp_Object elt; | 33 | * Lisp_Object elt; |
| 34 | * | 34 | * |
| 35 | * while (!NULL (args)) | 35 | * while (!NILP (args)) |
| 36 | * { | 36 | * { |
| 37 | * elt = Fcar (args); | 37 | * elt = Fcar (args); |
| 38 | * Ffset (Fcar (elt), Fcons (Qmocklisp, Fcdr (elt))); | 38 | * Ffset (Fcar (elt), Fcons (Qmocklisp, Fcdr (elt))); |
| @@ -50,11 +50,11 @@ DEFUN ("ml-if", Fml_if, Sml_if, 0, UNEVALLED, 0, "Mocklisp version of `if'.") | |||
| 50 | struct gcpro gcpro1; | 50 | struct gcpro gcpro1; |
| 51 | 51 | ||
| 52 | GCPRO1 (args); | 52 | GCPRO1 (args); |
| 53 | while (!NULL (args)) | 53 | while (!NILP (args)) |
| 54 | { | 54 | { |
| 55 | val = Feval (Fcar (args)); | 55 | val = Feval (Fcar (args)); |
| 56 | args = Fcdr (args); | 56 | args = Fcdr (args); |
| 57 | if (NULL (args)) break; | 57 | if (NILP (args)) break; |
| 58 | if (XINT (val)) | 58 | if (XINT (val)) |
| 59 | { | 59 | { |
| 60 | val = Feval (Fcar (args)); | 60 | val = Feval (Fcar (args)); |
| @@ -156,7 +156,7 @@ DEFUN ("ml-prefix-argument-loop", Fml_prefix_argument_loop, Sml_prefix_argument_ | |||
| 156 | struct gcpro gcpro1; | 156 | struct gcpro gcpro1; |
| 157 | 157 | ||
| 158 | /* Set `arg' in case we call a built-in function that looks at it. Still are a few. */ | 158 | /* Set `arg' in case we call a built-in function that looks at it. Still are a few. */ |
| 159 | if (NULL (Vcurrent_prefix_arg)) | 159 | if (NILP (Vcurrent_prefix_arg)) |
| 160 | i = 1; | 160 | i = 1; |
| 161 | else | 161 | else |
| 162 | { | 162 | { |
diff --git a/src/mocklisp.h b/src/mocklisp.h index e381bb23f8b..56ff3f7a1de 100644 --- a/src/mocklisp.h +++ b/src/mocklisp.h | |||
| @@ -28,4 +28,4 @@ extern Lisp_Object Fml_arg (); | |||
| 28 | extern Lisp_Object Fml_interactive (); | 28 | extern Lisp_Object Fml_interactive (); |
| 29 | extern Lisp_Object Fml_provide_prefix_argument (); | 29 | extern Lisp_Object Fml_provide_prefix_argument (); |
| 30 | extern Lisp_Object Fml_prefix_argument_loop (); | 30 | extern Lisp_Object Fml_prefix_argument_loop (); |
| 31 | extern Lisp_Object FInsStr (); | 31 | extern Lisp_Object Finsert_string (); |
diff --git a/src/ndir.h b/src/ndir.h new file mode 100644 index 00000000000..438d5c20a12 --- /dev/null +++ b/src/ndir.h | |||
| @@ -0,0 +1,51 @@ | |||
| 1 | /* | ||
| 2 | <dir.h> -- definitions for 4.2BSD-compatible directory access | ||
| 3 | |||
| 4 | last edit: 09-Jul-1983 D A Gwyn | ||
| 5 | */ | ||
| 6 | |||
| 7 | #ifdef VMS | ||
| 8 | #ifndef FAB$C_BID | ||
| 9 | #include <fab.h> | ||
| 10 | #endif | ||
| 11 | #ifndef NAM$C_BID | ||
| 12 | #include <nam.h> | ||
| 13 | #endif | ||
| 14 | #ifndef RMS$_SUC | ||
| 15 | #include <rmsdef.h> | ||
| 16 | #endif | ||
| 17 | #include "dir.h" | ||
| 18 | #endif /* VMS */ | ||
| 19 | |||
| 20 | #define DIRBLKSIZ 512 /* size of directory block */ | ||
| 21 | #ifdef VMS | ||
| 22 | #define MAXNAMLEN (DIR$S_NAME + 7) /* 80 plus room for version #. */ | ||
| 23 | #define MAXFULLSPEC NAM$C_MAXRSS /* Maximum full spec */ | ||
| 24 | #else | ||
| 25 | #define MAXNAMLEN 15 /* maximum filename length */ | ||
| 26 | #endif /* VMS */ | ||
| 27 | /* NOTE: MAXNAMLEN must be one less than a multiple of 4 */ | ||
| 28 | |||
| 29 | struct direct /* data from readdir() */ | ||
| 30 | { | ||
| 31 | long d_ino; /* inode number of entry */ | ||
| 32 | unsigned short d_reclen; /* length of this record */ | ||
| 33 | unsigned short d_namlen; /* length of string in d_name */ | ||
| 34 | char d_name[MAXNAMLEN+1]; /* name of file */ | ||
| 35 | }; | ||
| 36 | |||
| 37 | typedef struct | ||
| 38 | { | ||
| 39 | int dd_fd; /* file descriptor */ | ||
| 40 | int dd_loc; /* offset in block */ | ||
| 41 | int dd_size; /* amount of valid data */ | ||
| 42 | char dd_buf[DIRBLKSIZ]; /* directory block */ | ||
| 43 | } DIR; /* stream data from opendir() */ | ||
| 44 | |||
| 45 | extern DIR *opendir(); | ||
| 46 | extern struct direct *readdir(); | ||
| 47 | extern long telldir(); | ||
| 48 | extern void seekdir(); | ||
| 49 | extern void closedir(); | ||
| 50 | |||
| 51 | #define rewinddir( dirp ) seekdir( dirp, 0L ) | ||
diff --git a/src/param.h b/src/param.h new file mode 100644 index 00000000000..1b27b50a276 --- /dev/null +++ b/src/param.h | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | /* This is so that Emacs can run on VMS... */ | ||
| 2 | #define EXEC_PAGESIZE 512 | ||
diff --git a/src/point.h b/src/point.h new file mode 100644 index 00000000000..7bae693f2d4 --- /dev/null +++ b/src/point.h | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | #define point_width 5 | ||
| 2 | #define point_height 19 | ||
| 3 | static char point_bits[] = { | ||
| 4 | 0x1f, 0x0e, 0x0e, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
| 5 | 0x00, 0x00, 0x04, 0x04, 0x0e, 0x0e, 0x1f}; | ||
diff --git a/src/pre-crt0.c b/src/pre-crt0.c new file mode 100644 index 00000000000..67fd31cd6ac --- /dev/null +++ b/src/pre-crt0.c | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | /* This file is loaded before crt0.o on machines where we do not | ||
| 2 | remap part of the data space into text space in unexec. | ||
| 3 | On these machines, there is no problem with standard crt0.o's | ||
| 4 | that make environ an initialized variable. However, we do | ||
| 5 | need to make sure the label data_start exists anyway. */ | ||
| 6 | |||
| 7 | /* Create a label to appear at the beginning of data space. */ | ||
| 8 | |||
| 9 | int data_start = 0; | ||
diff --git a/src/puresize.h b/src/puresize.h index 4934ba5f5bc..9473d3df5e7 100644 --- a/src/puresize.h +++ b/src/puresize.h | |||
| @@ -21,9 +21,19 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |||
| 21 | 21 | ||
| 22 | At one point, this was defined in config.h, meaning that changing | 22 | At one point, this was defined in config.h, meaning that changing |
| 23 | PURESIZE would make Make recompile all of Emacs. But only a few | 23 | PURESIZE would make Make recompile all of Emacs. But only a few |
| 24 | files actually use PURESIZE, so we split it out to its own .h file. */ | 24 | files actually use PURESIZE, so we split it out to its own .h file. |
| 25 | 25 | ||
| 26 | Make sure to include this file after config.h, since that tells us | ||
| 27 | whether we are running X windows, which tells us how much pure | ||
| 28 | storage to allocate. */ | ||
| 29 | |||
| 30 | #ifndef PURESIZE | ||
| 31 | #ifdef HAVE_X_WINDOWS | ||
| 26 | #define PURESIZE 200000 | 32 | #define PURESIZE 200000 |
| 33 | #else | ||
| 34 | #define PURESIZE 196000 | ||
| 35 | #endif | ||
| 36 | #endif | ||
| 27 | 37 | ||
| 28 | #ifdef VIRT_ADDR_VARIES | 38 | #ifdef VIRT_ADDR_VARIES |
| 29 | 39 | ||
diff --git a/src/sink.h b/src/sink.h new file mode 100644 index 00000000000..1eb6770c83f --- /dev/null +++ b/src/sink.h | |||
| @@ -0,0 +1,91 @@ | |||
| 1 | #define sink_width 48 | ||
| 2 | #define sink_height 48 | ||
| 3 | #ifdef HAVE_X11 | ||
| 4 | static char sink_bits[] = { | ||
| 5 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 6 | 0xff, 0xff, 0xff, 0xff, 0x80, 0x9f, | ||
| 7 | 0xff, 0xff, 0xff, 0xff, 0x9f, 0x9f, | ||
| 8 | 0xff, 0xff, 0xff, 0xff, 0x00, 0x80, | ||
| 9 | 0xff, 0xff, 0xff, 0x7f, 0xfe, 0xbf, | ||
| 10 | 0xff, 0xff, 0xff, 0x7f, 0x03, 0xa0, | ||
| 11 | 0xff, 0xff, 0xff, 0x7f, 0xfd, 0xaf, | ||
| 12 | 0xff, 0xff, 0xff, 0x3f, 0xf9, 0xaf, | ||
| 13 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xaf, | ||
| 14 | 0xff, 0xff, 0xff, 0xff, 0xfc, 0xaf, | ||
| 15 | 0xff, 0xff, 0xff, 0x7f, 0xf8, 0xaf, | ||
| 16 | 0xff, 0xff, 0xff, 0xff, 0xfc, 0xaf, | ||
| 17 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xaf, | ||
| 18 | 0xff, 0xff, 0xff, 0xbf, 0xf7, 0xaf, | ||
| 19 | 0xff, 0xff, 0xff, 0x3f, 0xf3, 0xaf, | ||
| 20 | 0xff, 0xff, 0xff, 0xff, 0xfc, 0xaf, | ||
| 21 | 0x3f, 0x00, 0x00, 0x00, 0x00, 0x20, | ||
| 22 | 0x7f, 0x00, 0x00, 0x00, 0x00, 0xe0, | ||
| 23 | 0xdf, 0xf8, 0xff, 0xff, 0xff, 0x07, | ||
| 24 | 0xcf, 0xf9, 0x0f, 0xff, 0xff, 0xe7, | ||
| 25 | 0xcf, 0xf9, 0xf7, 0xff, 0xff, 0xe7, | ||
| 26 | 0xff, 0xf9, 0xf7, 0x63, 0xfb, 0xe7, | ||
| 27 | 0xff, 0xf9, 0x37, 0x5a, 0xfb, 0xe7, | ||
| 28 | 0xcf, 0xf9, 0xf7, 0x5a, 0xfb, 0xe7, | ||
| 29 | 0xcf, 0xf9, 0xf7, 0x5a, 0xf9, 0xe7, | ||
| 30 | 0xef, 0xf9, 0x0f, 0xdb, 0xfa, 0xe7, | ||
| 31 | 0xff, 0xf9, 0xff, 0xff, 0xff, 0xe7, | ||
| 32 | 0xdf, 0xf9, 0xff, 0xff, 0xff, 0xe7, | ||
| 33 | 0xcf, 0x19, 0xfc, 0xff, 0xff, 0xe7, | ||
| 34 | 0xcf, 0xd9, 0xff, 0xff, 0xff, 0xe7, | ||
| 35 | 0xff, 0xd9, 0x47, 0xce, 0x73, 0xe6, | ||
| 36 | 0xff, 0x19, 0xb6, 0xb5, 0xad, 0xe7, | ||
| 37 | 0xcf, 0xd9, 0xb7, 0xb5, 0x7d, 0xe6, | ||
| 38 | 0xc7, 0xd9, 0xb7, 0xb5, 0xed, 0xe5, | ||
| 39 | 0xef, 0x19, 0xb4, 0x4d, 0x73, 0xe6, | ||
| 40 | 0xff, 0xf1, 0xff, 0xff, 0xff, 0xe3, | ||
| 41 | 0xff, 0x03, 0x80, 0x03, 0x00, 0xf0, | ||
| 42 | 0xef, 0x07, 0x00, 0x01, 0x00, 0xf8, | ||
| 43 | 0xc7, 0xff, 0x3f, 0xf9, 0xff, 0xff, | ||
| 44 | 0xe7, 0xff, 0x7f, 0xfd, 0xe0, 0xff, | ||
| 45 | 0xff, 0xff, 0x7f, 0x7d, 0xdf, 0xff, | ||
| 46 | 0xff, 0xff, 0x7f, 0xbd, 0xb1, 0xff, | ||
| 47 | 0xff, 0xff, 0x7f, 0xbb, 0xae, 0xff, | ||
| 48 | 0xef, 0xff, 0xff, 0xda, 0xae, 0xff, | ||
| 49 | 0xc7, 0xff, 0xff, 0x66, 0xaf, 0xff, | ||
| 50 | 0xe7, 0xff, 0xff, 0xbd, 0xaf, 0xff, | ||
| 51 | 0xff, 0xff, 0xff, 0xc3, 0xaf, 0xff, | ||
| 52 | 0xff, 0xff, 0xff, 0xff, 0xaf, 0xff}; | ||
| 53 | #else | ||
| 54 | short sink_bits[] = { | ||
| 55 | 0xffff, 0xffff, 0xffff, 0xffff, | ||
| 56 | 0xffff, 0x9f80, 0xffff, 0xffff, | ||
| 57 | 0x9f9f, 0xffff, 0xffff, 0x8000, | ||
| 58 | 0xffff, 0x7fff, 0xbffe, 0xffff, | ||
| 59 | 0x7fff, 0xa003, 0xffff, 0x7fff, | ||
| 60 | 0xaffd, 0xffff, 0x3fff, 0xaff9, | ||
| 61 | 0xffff, 0xffff, 0xafff, 0xffff, | ||
| 62 | 0xffff, 0xaffc, 0xffff, 0x7fff, | ||
| 63 | 0xaff8, 0xffff, 0xffff, 0xaffc, | ||
| 64 | 0xffff, 0xffff, 0xafff, 0xffff, | ||
| 65 | 0xbfff, 0xaff7, 0xffff, 0x3fff, | ||
| 66 | 0xaff3, 0xffff, 0xffff, 0xaffc, | ||
| 67 | 0x003f, 0x0000, 0x2000, 0x007f, | ||
| 68 | 0x0000, 0xe000, 0xf8df, 0xffff, | ||
| 69 | 0x07ff, 0xf9cf, 0xff0f, 0xe7ff, | ||
| 70 | 0xf9cf, 0xfff7, 0xe7ff, 0xf9ff, | ||
| 71 | 0x63f7, 0xe7fb, 0xf9ff, 0x5a37, | ||
| 72 | 0xe7fb, 0xf9cf, 0x5af7, 0xe7fb, | ||
| 73 | 0xf9cf, 0x5af7, 0xe7f9, 0xf9ef, | ||
| 74 | 0xdb0f, 0xe7fa, 0xf9ff, 0xffff, | ||
| 75 | 0xe7ff, 0xf9df, 0xffff, 0xe7ff, | ||
| 76 | 0x19cf, 0xfffc, 0xe7ff, 0xd9cf, | ||
| 77 | 0xffff, 0xe7ff, 0xd9ff, 0xce47, | ||
| 78 | 0xe673, 0x19ff, 0xb5b6, 0xe7ad, | ||
| 79 | 0xd9cf, 0xb5b7, 0xe67d, 0xd9c7, | ||
| 80 | 0xb5b7, 0xe5ed, 0x19ef, 0x4db4, | ||
| 81 | 0xe673, 0xf1ff, 0xffff, 0xe3ff, | ||
| 82 | 0x03ff, 0x0380, 0xf000, 0x07ef, | ||
| 83 | 0x0100, 0xf800, 0xffc7, 0xf93f, | ||
| 84 | 0xffff, 0xffe7, 0xfd7f, 0xffe0, | ||
| 85 | 0xffff, 0x7d7f, 0xffdf, 0xffff, | ||
| 86 | 0xbd7f, 0xffb1, 0xffff, 0xbb7f, | ||
| 87 | 0xffae, 0xffef, 0xdaff, 0xffae, | ||
| 88 | 0xffc7, 0x66ff, 0xffaf, 0xffe7, | ||
| 89 | 0xbdff, 0xffaf, 0xffff, 0xc3ff, | ||
| 90 | 0xffaf, 0xffff, 0xffff, 0xffaf}; | ||
| 91 | #endif /* HAVE_X11 */ | ||
diff --git a/src/sink11.h b/src/sink11.h new file mode 100644 index 00000000000..dec0280a72b --- /dev/null +++ b/src/sink11.h | |||
| @@ -0,0 +1,51 @@ | |||
| 1 | #define sink_width 48 | ||
| 2 | #define sink_height 48 | ||
| 3 | static char sink_bits[] = { | ||
| 4 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 5 | 0xff, 0xff, 0xff, 0xff, 0x80, 0x9f, | ||
| 6 | 0xff, 0xff, 0xff, 0xff, 0x9f, 0x9f, | ||
| 7 | 0xff, 0xff, 0xff, 0xff, 0x00, 0x80, | ||
| 8 | 0xff, 0xff, 0xff, 0x7f, 0xfe, 0xbf, | ||
| 9 | 0xff, 0xff, 0xff, 0x7f, 0x03, 0xa0, | ||
| 10 | 0xff, 0xff, 0xff, 0x7f, 0xfd, 0xaf, | ||
| 11 | 0xff, 0xff, 0xff, 0x3f, 0xf9, 0xaf, | ||
| 12 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xaf, | ||
| 13 | 0xff, 0xff, 0xff, 0xff, 0xfc, 0xaf, | ||
| 14 | 0xff, 0xff, 0xff, 0x7f, 0xf8, 0xaf, | ||
| 15 | 0xff, 0xff, 0xff, 0xff, 0xfc, 0xaf, | ||
| 16 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xaf, | ||
| 17 | 0xff, 0xff, 0xff, 0xbf, 0xf7, 0xaf, | ||
| 18 | 0xff, 0xff, 0xff, 0x3f, 0xf3, 0xaf, | ||
| 19 | 0xff, 0xff, 0xff, 0xff, 0xfc, 0xaf, | ||
| 20 | 0x3f, 0x00, 0x00, 0x00, 0x00, 0x20, | ||
| 21 | 0x7f, 0x00, 0x00, 0x00, 0x00, 0xe0, | ||
| 22 | 0xdf, 0xf8, 0xff, 0xff, 0xff, 0x07, | ||
| 23 | 0xcf, 0xf9, 0x0f, 0xff, 0xff, 0xe7, | ||
| 24 | 0xcf, 0xf9, 0xf7, 0xff, 0xff, 0xe7, | ||
| 25 | 0xff, 0xf9, 0xf7, 0x63, 0xfb, 0xe7, | ||
| 26 | 0xff, 0xf9, 0x37, 0x5a, 0xfb, 0xe7, | ||
| 27 | 0xcf, 0xf9, 0xf7, 0x5a, 0xfb, 0xe7, | ||
| 28 | 0xcf, 0xf9, 0xf7, 0x5a, 0xf9, 0xe7, | ||
| 29 | 0xef, 0xf9, 0x0f, 0xdb, 0xfa, 0xe7, | ||
| 30 | 0xff, 0xf9, 0xff, 0xff, 0xff, 0xe7, | ||
| 31 | 0xdf, 0xf9, 0xff, 0xff, 0xff, 0xe7, | ||
| 32 | 0xcf, 0x19, 0xfc, 0xff, 0xff, 0xe7, | ||
| 33 | 0xcf, 0xd9, 0xff, 0xff, 0xff, 0xe7, | ||
| 34 | 0xff, 0xd9, 0x47, 0xce, 0x73, 0xe6, | ||
| 35 | 0xff, 0x19, 0xb6, 0xb5, 0xad, 0xe7, | ||
| 36 | 0xcf, 0xd9, 0xb7, 0xb5, 0x7d, 0xe6, | ||
| 37 | 0xc7, 0xd9, 0xb7, 0xb5, 0xed, 0xe5, | ||
| 38 | 0xef, 0x19, 0xb4, 0x4d, 0x73, 0xe6, | ||
| 39 | 0xff, 0xf1, 0xff, 0xff, 0xff, 0xe3, | ||
| 40 | 0xff, 0x03, 0x80, 0x03, 0x00, 0xf0, | ||
| 41 | 0xef, 0x07, 0x00, 0x01, 0x00, 0xf8, | ||
| 42 | 0xc7, 0xff, 0x3f, 0xf9, 0xff, 0xff, | ||
| 43 | 0xe7, 0xff, 0x7f, 0xfd, 0xe0, 0xff, | ||
| 44 | 0xff, 0xff, 0x7f, 0x7d, 0xdf, 0xff, | ||
| 45 | 0xff, 0xff, 0x7f, 0xbd, 0xb1, 0xff, | ||
| 46 | 0xff, 0xff, 0x7f, 0xbb, 0xae, 0xff, | ||
| 47 | 0xef, 0xff, 0xff, 0xda, 0xae, 0xff, | ||
| 48 | 0xc7, 0xff, 0xff, 0x66, 0xaf, 0xff, | ||
| 49 | 0xe7, 0xff, 0xff, 0xbd, 0xaf, 0xff, | ||
| 50 | 0xff, 0xff, 0xff, 0xc3, 0xaf, 0xff, | ||
| 51 | 0xff, 0xff, 0xff, 0xff, 0xaf, 0xff}; | ||
diff --git a/src/sink11mask.h b/src/sink11mask.h new file mode 100644 index 00000000000..b0a6e0c6f35 --- /dev/null +++ b/src/sink11mask.h | |||
| @@ -0,0 +1,51 @@ | |||
| 1 | #define sink_mask_width 48 | ||
| 2 | #define sink_mask_height 48 | ||
| 3 | static char sink_mask_bits[] = { | ||
| 4 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 5 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 6 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 7 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 8 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 9 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 10 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 11 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 12 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 13 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 14 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 15 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 16 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 17 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 18 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 19 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 20 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 21 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 22 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 23 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 24 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 25 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 26 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 27 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 28 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 29 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 30 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 31 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 32 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 33 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 34 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 35 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 36 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 37 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 38 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 39 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 40 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 41 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 42 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 43 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 44 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 45 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 46 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 47 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 48 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 49 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 50 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 51 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; | ||
diff --git a/src/terminfo.c b/src/terminfo.c new file mode 100644 index 00000000000..af057133e50 --- /dev/null +++ b/src/terminfo.c | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | /* Interface from Emacs to terminfo. | ||
| 2 | Copyright (C) 1985, 1986 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is part of GNU Emacs. | ||
| 5 | |||
| 6 | GNU Emacs is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 1, or (at your option) | ||
| 9 | any later version. | ||
| 10 | |||
| 11 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with GNU Emacs; see the file COPYING. If not, write to | ||
| 18 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
| 19 | |||
| 20 | /* Define these variables that serve as global parameters to termcap, | ||
| 21 | so that we do not need to conditionalize the places in Emacs | ||
| 22 | that set them. */ | ||
| 23 | |||
| 24 | char *UP, *BC, PC; | ||
| 25 | short ospeed; | ||
| 26 | |||
| 27 | static buffer[512]; | ||
| 28 | |||
| 29 | /* Interface to curses/terminfo library. | ||
| 30 | Turns out that all of the terminfo-level routines look | ||
| 31 | like their termcap counterparts except for tparm, which replaces | ||
| 32 | tgoto. Not only is the calling sequence different, but the string | ||
| 33 | format is different too. | ||
| 34 | */ | ||
| 35 | |||
| 36 | char * | ||
| 37 | tparam (string, outstring, len, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) | ||
| 38 | char *string; | ||
| 39 | char *outstring; | ||
| 40 | int arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9; | ||
| 41 | { | ||
| 42 | char *temp; | ||
| 43 | extern char *tparm(); | ||
| 44 | |||
| 45 | temp = tparm (string, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); | ||
| 46 | if (outstring == 0) | ||
| 47 | outstring = ((char *) (malloc ((strlen (temp)) + 1))); | ||
| 48 | strcpy (outstring, temp); | ||
| 49 | return outstring; | ||
| 50 | } | ||
| @@ -3,20 +3,19 @@ | |||
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
| 6 | GNU Emacs is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 1, or (at your option) | ||
| 9 | any later version. | ||
| 10 | |||
| 6 | GNU Emacs is distributed in the hope that it will be useful, | 11 | GNU Emacs is distributed in the hope that it will be useful, |
| 7 | but WITHOUT ANY WARRANTY. No author or distributor | 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 8 | accepts responsibility to anyone for the consequences of using it | 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 9 | or for whether it serves any particular purpose or works at all, | 14 | GNU General Public License for more details. |
| 10 | unless he says so in writing. Refer to the GNU Emacs General Public | ||
| 11 | License for full details. | ||
| 12 | 15 | ||
| 13 | Everyone is granted permission to copy, modify and redistribute | 16 | You should have received a copy of the GNU General Public License |
| 14 | GNU Emacs, but only under the conditions described in the | 17 | along with GNU Emacs; see the file COPYING. If not, write to |
| 15 | GNU Emacs General Public License. A copy of this license is | 18 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ |
| 16 | supposed to have been given to you along with GNU Emacs so you | ||
| 17 | can know your rights and responsibilities. It should be in a | ||
| 18 | file named COPYING. Among other things, the copyright notice | ||
| 19 | and this notice must be preserved on all copies. */ | ||
| 20 | 19 | ||
| 21 | /* | 20 | /* |
| 22 | * User Authorization File record formats | 21 | * User Authorization File record formats |
diff --git a/src/unexconvex.c b/src/unexconvex.c new file mode 100644 index 00000000000..09a7dfff400 --- /dev/null +++ b/src/unexconvex.c | |||
| @@ -0,0 +1,601 @@ | |||
| 1 | /* Modified version of unexec for convex machines. | ||
| 2 | Note that the GNU project considers support for the peculiarities | ||
| 3 | of the Convex operating system a peripheral activity which should | ||
| 4 | not be allowed to divert effort from development of the GNU system. | ||
| 5 | Changes in this code will be installed when Convex system | ||
| 6 | maintainers send them in, but aside from that we don't plan to | ||
| 7 | think about it, or about whether other Emacs maintenance might | ||
| 8 | break it. | ||
| 9 | |||
| 10 | Copyright (C) 1985, 1986, 1988 Free Software Foundation, Inc. | ||
| 11 | |||
| 12 | This file is part of GNU Emacs. | ||
| 13 | |||
| 14 | GNU Emacs is free software; you can redistribute it and/or modify | ||
| 15 | it under the terms of the GNU General Public License as published by | ||
| 16 | the Free Software Foundation; either version 1, or (at your option) | ||
| 17 | any later version. | ||
| 18 | |||
| 19 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 20 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 22 | GNU General Public License for more details. | ||
| 23 | |||
| 24 | You should have received a copy of the GNU General Public License | ||
| 25 | along with GNU Emacs; see the file COPYING. If not, write to | ||
| 26 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
| 27 | |||
| 28 | |||
| 29 | /* modified for C-1 arch by jthomp@convex 871103 */ | ||
| 30 | /* Corrected to support convex SOFF object file formats and thread specific | ||
| 31 | * regions. streepy@convex 890302 | ||
| 32 | */ | ||
| 33 | |||
| 34 | /* | ||
| 35 | * unexec.c - Convert a running program into an a.out file. | ||
| 36 | * | ||
| 37 | * Author: Spencer W. Thomas | ||
| 38 | * Computer Science Dept. | ||
| 39 | * University of Utah | ||
| 40 | * Date: Tue Mar 2 1982 | ||
| 41 | * Modified heavily since then. | ||
| 42 | * | ||
| 43 | * Synopsis: | ||
| 44 | * unexec (new_name, a_name, data_start, bss_start, entry_address) | ||
| 45 | * char *new_name, *a_name; | ||
| 46 | * unsigned data_start, bss_start, entry_address; | ||
| 47 | * | ||
| 48 | * Takes a snapshot of the program and makes an a.out format file in the | ||
| 49 | * file named by the string argument new_name. | ||
| 50 | * If a_name is non-NULL, the symbol table will be taken from the given file. | ||
| 51 | * On some machines, an existing a_name file is required. | ||
| 52 | * | ||
| 53 | * The boundaries within the a.out file may be adjusted with the data_start | ||
| 54 | * and bss_start arguments. Either or both may be given as 0 for defaults. | ||
| 55 | * | ||
| 56 | * Data_start gives the boundary between the text segment and the data | ||
| 57 | * segment of the program. The text segment can contain shared, read-only | ||
| 58 | * program code and literal data, while the data segment is always unshared | ||
| 59 | * and unprotected. Data_start gives the lowest unprotected address. | ||
| 60 | * The value you specify may be rounded down to a suitable boundary | ||
| 61 | * as required by the machine you are using. | ||
| 62 | * | ||
| 63 | * Specifying zero for data_start means the boundary between text and data | ||
| 64 | * should not be the same as when the program was loaded. | ||
| 65 | * If NO_REMAP is defined, the argument data_start is ignored and the | ||
| 66 | * segment boundaries are never changed. | ||
| 67 | * | ||
| 68 | * Bss_start indicates how much of the data segment is to be saved in the | ||
| 69 | * a.out file and restored when the program is executed. It gives the lowest | ||
| 70 | * unsaved address, and is rounded up to a page boundary. The default when 0 | ||
| 71 | * is given assumes that the entire data segment is to be stored, including | ||
| 72 | * the previous data and bss as well as any additional storage allocated with | ||
| 73 | * break (2). | ||
| 74 | * | ||
| 75 | * The new file is set up to start at entry_address. | ||
| 76 | * | ||
| 77 | * If you make improvements I'd like to get them too. | ||
| 78 | * harpo!utah-cs!thomas, thomas@Utah-20 | ||
| 79 | * | ||
| 80 | */ | ||
| 81 | |||
| 82 | /* There are several compilation parameters affecting unexec: | ||
| 83 | |||
| 84 | * COFF | ||
| 85 | |||
| 86 | Define this if your system uses COFF for executables. | ||
| 87 | Otherwise we assume you use Berkeley format. | ||
| 88 | |||
| 89 | * NO_REMAP | ||
| 90 | |||
| 91 | Define this if you do not want to try to save Emacs's pure data areas | ||
| 92 | as part of the text segment. | ||
| 93 | |||
| 94 | Saving them as text is good because it allows users to share more. | ||
| 95 | |||
| 96 | However, on machines that locate the text area far from the data area, | ||
| 97 | the boundary cannot feasibly be moved. Such machines require | ||
| 98 | NO_REMAP. | ||
| 99 | |||
| 100 | Also, remapping can cause trouble with the built-in startup routine | ||
| 101 | /lib/crt0.o, which defines `environ' as an initialized variable. | ||
| 102 | Dumping `environ' as pure does not work! So, to use remapping, | ||
| 103 | you must write a startup routine for your machine in Emacs's crt0.c. | ||
| 104 | If NO_REMAP is defined, Emacs uses the system's crt0.o. | ||
| 105 | |||
| 106 | * SECTION_ALIGNMENT | ||
| 107 | |||
| 108 | Some machines that use COFF executables require that each section | ||
| 109 | start on a certain boundary *in the COFF file*. Such machines should | ||
| 110 | define SECTION_ALIGNMENT to a mask of the low-order bits that must be | ||
| 111 | zero on such a boundary. This mask is used to control padding between | ||
| 112 | segments in the COFF file. | ||
| 113 | |||
| 114 | If SECTION_ALIGNMENT is not defined, the segments are written | ||
| 115 | consecutively with no attempt at alignment. This is right for | ||
| 116 | unmodified system V. | ||
| 117 | |||
| 118 | * SEGMENT_MASK | ||
| 119 | |||
| 120 | Some machines require that the beginnings and ends of segments | ||
| 121 | *in core* be on certain boundaries. For most machines, a page | ||
| 122 | boundary is sufficient. That is the default. When a larger | ||
| 123 | boundary is needed, define SEGMENT_MASK to a mask of | ||
| 124 | the bits that must be zero on such a boundary. | ||
| 125 | |||
| 126 | * A_TEXT_OFFSET(HDR) | ||
| 127 | |||
| 128 | Some machines count the a.out header as part of the size of the text | ||
| 129 | segment (a_text); they may actually load the header into core as the | ||
| 130 | first data in the text segment. Some have additional padding between | ||
| 131 | the header and the real text of the program that is counted in a_text. | ||
| 132 | |||
| 133 | For these machines, define A_TEXT_OFFSET(HDR) to examine the header | ||
| 134 | structure HDR and return the number of bytes to add to `a_text' | ||
| 135 | before writing it (above and beyond the number of bytes of actual | ||
| 136 | program text). HDR's standard fields are already correct, except that | ||
| 137 | this adjustment to the `a_text' field has not yet been made; | ||
| 138 | thus, the amount of offset can depend on the data in the file. | ||
| 139 | |||
| 140 | * A_TEXT_SEEK(HDR) | ||
| 141 | |||
| 142 | If defined, this macro specifies the number of bytes to seek into the | ||
| 143 | a.out file before starting to write the text segment.a | ||
| 144 | |||
| 145 | * EXEC_MAGIC | ||
| 146 | |||
| 147 | For machines using COFF, this macro, if defined, is a value stored | ||
| 148 | into the magic number field of the output file. | ||
| 149 | |||
| 150 | * ADJUST_EXEC_HEADER | ||
| 151 | |||
| 152 | This macro can be used to generate statements to adjust or | ||
| 153 | initialize nonstandard fields in the file header | ||
| 154 | |||
| 155 | * ADDR_CORRECT(ADDR) | ||
| 156 | |||
| 157 | Macro to correct an int which is the bit pattern of a pointer to a byte | ||
| 158 | into an int which is the number of a byte. | ||
| 159 | |||
| 160 | This macro has a default definition which is usually right. | ||
| 161 | This default definition is a no-op on most machines (where a | ||
| 162 | pointer looks like an int) but not on all machines. | ||
| 163 | |||
| 164 | */ | ||
| 165 | |||
| 166 | #include "config.h" | ||
| 167 | #define PERROR(file) report_error (file, new) | ||
| 168 | |||
| 169 | #include <a.out.h> | ||
| 170 | /* Define getpagesize () if the system does not. | ||
| 171 | Note that this may depend on symbols defined in a.out.h | ||
| 172 | */ | ||
| 173 | #include "getpagesize.h" | ||
| 174 | |||
| 175 | #include <sys/types.h> | ||
| 176 | #include <stdio.h> | ||
| 177 | #include <sys/stat.h> | ||
| 178 | #include <errno.h> | ||
| 179 | |||
| 180 | extern char *start_of_text (); /* Start of text */ | ||
| 181 | extern char *start_of_data (); /* Start of initialized data */ | ||
| 182 | |||
| 183 | #include <machine/filehdr.h> | ||
| 184 | #include <machine/opthdr.h> | ||
| 185 | #include <machine/scnhdr.h> | ||
| 186 | #include <machine/pte.h> | ||
| 187 | |||
| 188 | static long block_copy_start; /* Old executable start point */ | ||
| 189 | static struct filehdr f_hdr; /* File header */ | ||
| 190 | static struct opthdr f_ohdr; /* Optional file header (a.out) */ | ||
| 191 | long bias; /* Bias to add for growth */ | ||
| 192 | #define SYMS_START block_copy_start | ||
| 193 | |||
| 194 | static long text_scnptr; | ||
| 195 | static long data_scnptr; | ||
| 196 | |||
| 197 | static int pagemask; | ||
| 198 | static int pagesz; | ||
| 199 | |||
| 200 | static | ||
| 201 | report_error (file, fd) | ||
| 202 | char *file; | ||
| 203 | int fd; | ||
| 204 | { | ||
| 205 | if (fd) | ||
| 206 | close (fd); | ||
| 207 | error ("Failure operating on %s", file); | ||
| 208 | } | ||
| 209 | |||
| 210 | #define ERROR0(msg) report_error_1 (new, msg, 0, 0); return -1 | ||
| 211 | #define ERROR1(msg,x) report_error_1 (new, msg, x, 0); return -1 | ||
| 212 | #define ERROR2(msg,x,y) report_error_1 (new, msg, x, y); return -1 | ||
| 213 | |||
| 214 | static | ||
| 215 | report_error_1 (fd, msg, a1, a2) | ||
| 216 | int fd; | ||
| 217 | char *msg; | ||
| 218 | int a1, a2; | ||
| 219 | { | ||
| 220 | close (fd); | ||
| 221 | error (msg, a1, a2); | ||
| 222 | } | ||
| 223 | |||
| 224 | /* **************************************************************** | ||
| 225 | * unexec | ||
| 226 | * | ||
| 227 | * driving logic. | ||
| 228 | */ | ||
| 229 | unexec (new_name, a_name, data_start, bss_start, entry_address) | ||
| 230 | char *new_name, *a_name; | ||
| 231 | unsigned data_start, bss_start, entry_address; | ||
| 232 | { | ||
| 233 | int new, a_out = -1; | ||
| 234 | |||
| 235 | if (a_name && (a_out = open (a_name, 0)) < 0) { | ||
| 236 | PERROR (a_name); | ||
| 237 | } | ||
| 238 | if ((new = creat (new_name, 0666)) < 0) { | ||
| 239 | PERROR (new_name); | ||
| 240 | } | ||
| 241 | |||
| 242 | if (make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name) < 0 | ||
| 243 | || copy_text_and_data (new) < 0 | ||
| 244 | || copy_sym (new, a_out, a_name, new_name) < 0 ) { | ||
| 245 | close (new); | ||
| 246 | return -1; | ||
| 247 | } | ||
| 248 | |||
| 249 | close (new); | ||
| 250 | if (a_out >= 0) | ||
| 251 | close (a_out); | ||
| 252 | mark_x (new_name); | ||
| 253 | return 0; | ||
| 254 | } | ||
| 255 | |||
| 256 | /* **************************************************************** | ||
| 257 | * make_hdr | ||
| 258 | * | ||
| 259 | * Make the header in the new a.out from the header in core. | ||
| 260 | * Modify the text and data sizes. | ||
| 261 | */ | ||
| 262 | |||
| 263 | struct scnhdr *stbl; /* Table of all scnhdr's */ | ||
| 264 | struct scnhdr *f_thdr; /* Text section header */ | ||
| 265 | struct scnhdr *f_dhdr; /* Data section header */ | ||
| 266 | struct scnhdr *f_tdhdr; /* Thread Data section header */ | ||
| 267 | struct scnhdr *f_bhdr; /* Bss section header */ | ||
| 268 | struct scnhdr *f_tbhdr; /* Thread Bss section header */ | ||
| 269 | |||
| 270 | static int | ||
| 271 | make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name) | ||
| 272 | int new, a_out; | ||
| 273 | unsigned data_start, bss_start, entry_address; | ||
| 274 | char *a_name; | ||
| 275 | char *new_name; | ||
| 276 | { | ||
| 277 | register int scns; | ||
| 278 | unsigned int bss_end; | ||
| 279 | unsigned int eo_data; /* End of initialized data in new exec file */ | ||
| 280 | int scntype; /* Section type */ | ||
| 281 | int i; /* Var for sorting by vaddr */ | ||
| 282 | struct scnhdr scntemp; /* For swapping entries in sort */ | ||
| 283 | extern char *start_of_data(); | ||
| 284 | |||
| 285 | pagemask = (pagesz = getpagesize()) - 1; | ||
| 286 | |||
| 287 | /* Adjust text/data boundary. */ | ||
| 288 | if (!data_start) | ||
| 289 | data_start = (unsigned) start_of_data (); | ||
| 290 | |||
| 291 | data_start = data_start & ~pagemask; /* (Down) to page boundary. */ | ||
| 292 | |||
| 293 | bss_end = (sbrk(0) + pagemask) & ~pagemask; | ||
| 294 | |||
| 295 | /* Adjust data/bss boundary. */ | ||
| 296 | if (bss_start != 0) { | ||
| 297 | bss_start = (bss_start + pagemask) & ~pagemask;/* (Up) to page bdry. */ | ||
| 298 | if (bss_start > bss_end) { | ||
| 299 | ERROR1 ("unexec: Specified bss_start (%x) is past end of program", | ||
| 300 | bss_start); | ||
| 301 | } | ||
| 302 | } else | ||
| 303 | bss_start = bss_end; | ||
| 304 | |||
| 305 | if (data_start > bss_start) { /* Can't have negative data size. */ | ||
| 306 | ERROR2 ("unexec: data_start (%x) can't be greater than bss_start (%x)", | ||
| 307 | data_start, bss_start); | ||
| 308 | } | ||
| 309 | |||
| 310 | /* Salvage as much info from the existing file as possible */ | ||
| 311 | if (a_out < 0) { | ||
| 312 | ERROR0 ("can't build a COFF file from scratch yet"); | ||
| 313 | /*NOTREACHED*/ | ||
| 314 | } | ||
| 315 | |||
| 316 | if (read (a_out, &f_hdr, sizeof (f_hdr)) != sizeof (f_hdr)) { | ||
| 317 | PERROR (a_name); | ||
| 318 | } | ||
| 319 | block_copy_start += sizeof (f_hdr); | ||
| 320 | if (f_hdr.h_opthdr > 0) { | ||
| 321 | if (read (a_out, &f_ohdr, sizeof (f_ohdr)) != sizeof (f_ohdr)) { | ||
| 322 | PERROR (a_name); | ||
| 323 | } | ||
| 324 | block_copy_start += sizeof (f_ohdr); | ||
| 325 | } | ||
| 326 | |||
| 327 | /* Allocate room for scn headers */ | ||
| 328 | stbl = (struct scnhdr *)malloc( sizeof(struct scnhdr) * f_hdr.h_nscns ); | ||
| 329 | if( stbl == NULL ) { | ||
| 330 | ERROR0( "unexec: malloc of stbl failed" ); | ||
| 331 | } | ||
| 332 | |||
| 333 | f_tdhdr = f_tbhdr = NULL; | ||
| 334 | |||
| 335 | /* Loop through section headers, copying them in */ | ||
| 336 | for (scns = 0; scns < f_hdr.h_nscns; scns++) { | ||
| 337 | |||
| 338 | if( read( a_out, &stbl[scns], sizeof(*stbl)) != sizeof(*stbl)) { | ||
| 339 | PERROR (a_name); | ||
| 340 | } | ||
| 341 | |||
| 342 | scntype = stbl[scns].s_flags & S_TYPMASK; /* What type of section */ | ||
| 343 | |||
| 344 | if( stbl[scns].s_scnptr > 0L) { | ||
| 345 | if( block_copy_start < stbl[scns].s_scnptr + stbl[scns].s_size ) | ||
| 346 | block_copy_start = stbl[scns].s_scnptr + stbl[scns].s_size; | ||
| 347 | } | ||
| 348 | |||
| 349 | if( scntype == S_TEXT) { | ||
| 350 | f_thdr = &stbl[scns]; | ||
| 351 | } else if( scntype == S_DATA) { | ||
| 352 | f_dhdr = &stbl[scns]; | ||
| 353 | #ifdef S_TDATA | ||
| 354 | } else if( scntype == S_TDATA ) { | ||
| 355 | f_tdhdr = &stbl[scns]; | ||
| 356 | } else if( scntype == S_TBSS ) { | ||
| 357 | f_tbhdr = &stbl[scns]; | ||
| 358 | #endif /* S_TDATA (thread stuff) */ | ||
| 359 | |||
| 360 | } else if( scntype == S_BSS) { | ||
| 361 | f_bhdr = &stbl[scns]; | ||
| 362 | } | ||
| 363 | |||
| 364 | } | ||
| 365 | |||
| 366 | /* We will now convert TEXT and DATA into TEXT, BSS into DATA, and leave | ||
| 367 | * all thread stuff alone. | ||
| 368 | */ | ||
| 369 | |||
| 370 | /* Now we alter the contents of all the f_*hdr variables | ||
| 371 | to correspond to what we want to dump. */ | ||
| 372 | |||
| 373 | f_thdr->s_vaddr = (long) start_of_text (); | ||
| 374 | f_thdr->s_size = data_start - f_thdr->s_vaddr; | ||
| 375 | f_thdr->s_scnptr = pagesz; | ||
| 376 | f_thdr->s_relptr = 0; | ||
| 377 | f_thdr->s_nrel = 0; | ||
| 378 | |||
| 379 | eo_data = f_thdr->s_scnptr + f_thdr->s_size; | ||
| 380 | |||
| 381 | if( f_tdhdr ) { /* Process thread data */ | ||
| 382 | |||
| 383 | f_tdhdr->s_vaddr = data_start; | ||
| 384 | f_tdhdr->s_size += f_dhdr->s_size - (data_start - f_dhdr->s_vaddr); | ||
| 385 | f_tdhdr->s_scnptr = eo_data; | ||
| 386 | f_tdhdr->s_relptr = 0; | ||
| 387 | f_tdhdr->s_nrel = 0; | ||
| 388 | |||
| 389 | eo_data += f_tdhdr->s_size; | ||
| 390 | |||
| 391 | /* And now for DATA */ | ||
| 392 | |||
| 393 | f_dhdr->s_vaddr = f_bhdr->s_vaddr; /* Take BSS start address */ | ||
| 394 | f_dhdr->s_size = bss_end - f_bhdr->s_vaddr; | ||
| 395 | f_dhdr->s_scnptr = eo_data; | ||
| 396 | f_dhdr->s_relptr = 0; | ||
| 397 | f_dhdr->s_nrel = 0; | ||
| 398 | |||
| 399 | eo_data += f_dhdr->s_size; | ||
| 400 | |||
| 401 | } else { | ||
| 402 | |||
| 403 | f_dhdr->s_vaddr = data_start; | ||
| 404 | f_dhdr->s_size = bss_start - data_start; | ||
| 405 | f_dhdr->s_scnptr = eo_data; | ||
| 406 | f_dhdr->s_relptr = 0; | ||
| 407 | f_dhdr->s_nrel = 0; | ||
| 408 | |||
| 409 | eo_data += f_dhdr->s_size; | ||
| 410 | |||
| 411 | } | ||
| 412 | |||
| 413 | f_bhdr->s_vaddr = bss_start; | ||
| 414 | f_bhdr->s_size = bss_end - bss_start + pagesz /* fudge */; | ||
| 415 | f_bhdr->s_scnptr = 0; | ||
| 416 | f_bhdr->s_relptr = 0; | ||
| 417 | f_bhdr->s_nrel = 0; | ||
| 418 | |||
| 419 | text_scnptr = f_thdr->s_scnptr; | ||
| 420 | data_scnptr = f_dhdr->s_scnptr; | ||
| 421 | bias = eo_data - block_copy_start; | ||
| 422 | |||
| 423 | if (f_ohdr.o_symptr > 0L) { | ||
| 424 | f_ohdr.o_symptr += bias; | ||
| 425 | } | ||
| 426 | |||
| 427 | if (f_hdr.h_strptr > 0) { | ||
| 428 | f_hdr.h_strptr += bias; | ||
| 429 | } | ||
| 430 | |||
| 431 | if (write (new, &f_hdr, sizeof (f_hdr)) != sizeof (f_hdr)) { | ||
| 432 | PERROR (new_name); | ||
| 433 | } | ||
| 434 | |||
| 435 | if (write (new, &f_ohdr, sizeof (f_ohdr)) != sizeof (f_ohdr)) { | ||
| 436 | PERROR (new_name); | ||
| 437 | } | ||
| 438 | |||
| 439 | for( scns = 0; scns < f_hdr.h_nscns; scns++ ) { | ||
| 440 | |||
| 441 | /* This is a cheesey little loop to write out the section headers | ||
| 442 | * in order of increasing virtual address. Dull but effective. | ||
| 443 | */ | ||
| 444 | |||
| 445 | for( i = scns+1; i < f_hdr.h_nscns; i++ ) { | ||
| 446 | if( stbl[i].s_vaddr < stbl[scns].s_vaddr ) { /* Swap */ | ||
| 447 | scntemp = stbl[i]; | ||
| 448 | stbl[i] = stbl[scns]; | ||
| 449 | stbl[scns] = scntemp; | ||
| 450 | } | ||
| 451 | } | ||
| 452 | |||
| 453 | } | ||
| 454 | |||
| 455 | for( scns = 0; scns < f_hdr.h_nscns; scns++ ) { | ||
| 456 | |||
| 457 | if( write( new, &stbl[scns], sizeof(*stbl)) != sizeof(*stbl)) { | ||
| 458 | PERROR (new_name); | ||
| 459 | } | ||
| 460 | |||
| 461 | } | ||
| 462 | |||
| 463 | return (0); | ||
| 464 | |||
| 465 | } | ||
| 466 | |||
| 467 | /* **************************************************************** | ||
| 468 | * copy_text_and_data | ||
| 469 | * | ||
| 470 | * Copy the text and data segments from memory to the new a.out | ||
| 471 | */ | ||
| 472 | static int | ||
| 473 | copy_text_and_data (new) | ||
| 474 | int new; | ||
| 475 | { | ||
| 476 | register int scns; | ||
| 477 | |||
| 478 | for( scns = 0; scns < f_hdr.h_nscns; scns++ ) | ||
| 479 | write_segment( new, &stbl[scns] ); | ||
| 480 | |||
| 481 | return 0; | ||
| 482 | } | ||
| 483 | |||
| 484 | write_segment( new, sptr ) | ||
| 485 | int new; | ||
| 486 | struct scnhdr *sptr; | ||
| 487 | { | ||
| 488 | register char *ptr, *end; | ||
| 489 | register int nwrite, ret; | ||
| 490 | char buf[80]; | ||
| 491 | extern int errno; | ||
| 492 | char zeros[128]; | ||
| 493 | |||
| 494 | if( sptr->s_scnptr == 0 ) | ||
| 495 | return; /* Nothing to do */ | ||
| 496 | |||
| 497 | if( lseek( new, (long) sptr->s_scnptr, 0 ) == -1 ) | ||
| 498 | PERROR( "unexecing" ); | ||
| 499 | |||
| 500 | bzero (zeros, sizeof zeros); | ||
| 501 | |||
| 502 | ptr = (char *) sptr->s_vaddr; | ||
| 503 | end = ptr + sptr->s_size; | ||
| 504 | |||
| 505 | while( ptr < end ) { | ||
| 506 | |||
| 507 | /* distance to next multiple of 128. */ | ||
| 508 | nwrite = (((int) ptr + 128) & -128) - (int) ptr; | ||
| 509 | /* But not beyond specified end. */ | ||
| 510 | if (nwrite > end - ptr) nwrite = end - ptr; | ||
| 511 | ret = write (new, ptr, nwrite); | ||
| 512 | /* If write gets a page fault, it means we reached | ||
| 513 | a gap between the old text segment and the old data segment. | ||
| 514 | This gap has probably been remapped into part of the text segment. | ||
| 515 | So write zeros for it. */ | ||
| 516 | if (ret == -1 && errno == EFAULT) | ||
| 517 | write (new, zeros, nwrite); | ||
| 518 | else if (nwrite != ret) { | ||
| 519 | sprintf (buf, | ||
| 520 | "unexec write failure: addr 0x%x, fileno %d, size 0x%x, wrote 0x%x, errno %d", | ||
| 521 | ptr, new, nwrite, ret, errno); | ||
| 522 | PERROR (buf); | ||
| 523 | } | ||
| 524 | ptr += nwrite; | ||
| 525 | } | ||
| 526 | } | ||
| 527 | |||
| 528 | /* **************************************************************** | ||
| 529 | * copy_sym | ||
| 530 | * | ||
| 531 | * Copy the relocation information and symbol table from the a.out to the new | ||
| 532 | */ | ||
| 533 | static int | ||
| 534 | copy_sym (new, a_out, a_name, new_name) | ||
| 535 | int new, a_out; | ||
| 536 | char *a_name, *new_name; | ||
| 537 | { | ||
| 538 | char page[1024]; | ||
| 539 | int n; | ||
| 540 | |||
| 541 | if (a_out < 0) | ||
| 542 | return 0; | ||
| 543 | |||
| 544 | if (SYMS_START == 0L) | ||
| 545 | return 0; | ||
| 546 | |||
| 547 | lseek (a_out, SYMS_START, 0); /* Position a.out to symtab. */ | ||
| 548 | lseek( new, (long)f_ohdr.o_symptr, 0 ); | ||
| 549 | |||
| 550 | while ((n = read (a_out, page, sizeof page)) > 0) { | ||
| 551 | if (write (new, page, n) != n) { | ||
| 552 | PERROR (new_name); | ||
| 553 | } | ||
| 554 | } | ||
| 555 | if (n < 0) { | ||
| 556 | PERROR (a_name); | ||
| 557 | } | ||
| 558 | return 0; | ||
| 559 | } | ||
| 560 | |||
| 561 | /* **************************************************************** | ||
| 562 | * mark_x | ||
| 563 | * | ||
| 564 | * After succesfully building the new a.out, mark it executable | ||
| 565 | */ | ||
| 566 | static | ||
| 567 | mark_x (name) | ||
| 568 | char *name; | ||
| 569 | { | ||
| 570 | struct stat sbuf; | ||
| 571 | int um; | ||
| 572 | int new = 0; /* for PERROR */ | ||
| 573 | |||
| 574 | um = umask (777); | ||
| 575 | umask (um); | ||
| 576 | if (stat (name, &sbuf) == -1) { | ||
| 577 | PERROR (name); | ||
| 578 | } | ||
| 579 | sbuf.st_mode |= 0111 & ~um; | ||
| 580 | if (chmod (name, sbuf.st_mode) == -1) | ||
| 581 | PERROR (name); | ||
| 582 | } | ||
| 583 | |||
| 584 | /* Find the first pty letter. This is usually 'p', as in ptyp0, but | ||
| 585 | is sometimes configured down to 'm', 'n', or 'o' for some reason. */ | ||
| 586 | |||
| 587 | first_pty_letter () | ||
| 588 | { | ||
| 589 | struct stat buf; | ||
| 590 | char pty_name[16]; | ||
| 591 | char c; | ||
| 592 | |||
| 593 | for (c = 'o'; c >= 'a'; c--) | ||
| 594 | { | ||
| 595 | sprintf (pty_name, "/dev/pty%c0", c); | ||
| 596 | if (stat (pty_name, &buf) < 0) | ||
| 597 | return c + 1; | ||
| 598 | } | ||
| 599 | return 'a'; | ||
| 600 | } | ||
| 601 | |||
diff --git a/src/unexelf.c b/src/unexelf.c new file mode 100644 index 00000000000..784fab1e7ff --- /dev/null +++ b/src/unexelf.c | |||
| @@ -0,0 +1,703 @@ | |||
| 1 | /* Copyright (C) 1985, 1986, 1987, 1988 Free Software Foundation, Inc. | ||
| 2 | |||
| 3 | NO WARRANTY | ||
| 4 | |||
| 5 | BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY | ||
| 6 | NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT | ||
| 7 | WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC, | ||
| 8 | RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS" | ||
| 9 | WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, | ||
| 10 | BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND | ||
| 11 | FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY | ||
| 12 | AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE | ||
| 13 | DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR | ||
| 14 | CORRECTION. | ||
| 15 | |||
| 16 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M. | ||
| 17 | STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY | ||
| 18 | WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE | ||
| 19 | LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR | ||
| 20 | OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE | ||
| 21 | USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR | ||
| 22 | DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR | ||
| 23 | A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS | ||
| 24 | PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH | ||
| 25 | DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. | ||
| 26 | |||
| 27 | GENERAL PUBLIC LICENSE TO COPY | ||
| 28 | |||
| 29 | 1. You may copy and distribute verbatim copies of this source file | ||
| 30 | as you receive it, in any medium, provided that you conspicuously and | ||
| 31 | appropriately publish on each copy a valid copyright notice "Copyright | ||
| 32 | (C) 1987 Free Software Foundation, Inc."; and include following the | ||
| 33 | copyright notice a verbatim copy of the above disclaimer of warranty | ||
| 34 | and of this License. You may charge a distribution fee for the | ||
| 35 | physical act of transferring a copy. | ||
| 36 | |||
| 37 | 2. You may modify your copy or copies of this source file or | ||
| 38 | any portion of it, and copy and distribute such modifications under | ||
| 39 | the terms of Paragraph 1 above, provided that you also do the following: | ||
| 40 | |||
| 41 | a) cause the modified files to carry prominent notices stating | ||
| 42 | that you changed the files and the date of any change; and | ||
| 43 | |||
| 44 | b) cause the whole of any work that you distribute or publish, | ||
| 45 | that in whole or in part contains or is a derivative of this | ||
| 46 | program or any part thereof, to be licensed at no charge to all | ||
| 47 | third parties on terms identical to those contained in this | ||
| 48 | License Agreement (except that you may choose to grant more extensive | ||
| 49 | warranty protection to some or all third parties, at your option). | ||
| 50 | |||
| 51 | c) You may charge a distribution fee for the physical act of | ||
| 52 | transferring a copy, and you may at your option offer warranty | ||
| 53 | protection in exchange for a fee. | ||
| 54 | |||
| 55 | Mere aggregation of another unrelated program with this program (or its | ||
| 56 | derivative) on a volume of a storage or distribution medium does not bring | ||
| 57 | the other program under the scope of these terms. | ||
| 58 | |||
| 59 | 3. You may copy and distribute this program (or a portion or derivative | ||
| 60 | of it, under Paragraph 2) in object code or executable form under the terms | ||
| 61 | of Paragraphs 1 and 2 above provided that you also do one of the following: | ||
| 62 | |||
| 63 | a) accompany it with the complete corresponding machine-readable | ||
| 64 | source code, which must be distributed under the terms of | ||
| 65 | Paragraphs 1 and 2 above; or, | ||
| 66 | |||
| 67 | b) accompany it with a written offer, valid for at least three | ||
| 68 | years, to give any third party free (except for a nominal | ||
| 69 | shipping charge) a complete machine-readable copy of the | ||
| 70 | corresponding source code, to be distributed under the terms of | ||
| 71 | Paragraphs 1 and 2 above; or, | ||
| 72 | |||
| 73 | c) accompany it with the information you received as to where the | ||
| 74 | corresponding source code may be obtained. (This alternative is | ||
| 75 | allowed only for noncommercial distribution and only if you | ||
| 76 | received the program in object code or executable form alone.) | ||
| 77 | |||
| 78 | For an executable file, complete source code means all the source code for | ||
| 79 | all modules it contains; but, as a special exception, it need not include | ||
| 80 | source code for modules which are standard libraries that accompany the | ||
| 81 | operating system on which the executable file runs. | ||
| 82 | |||
| 83 | 4. You may not copy, sublicense, distribute or transfer this program | ||
| 84 | except as expressly provided under this License Agreement. Any attempt | ||
| 85 | otherwise to copy, sublicense, distribute or transfer this program is void and | ||
| 86 | your rights to use the program under this License agreement shall be | ||
| 87 | automatically terminated. However, parties who have received computer | ||
| 88 | software programs from you with this License Agreement will not have | ||
| 89 | their licenses terminated so long as such parties remain in full compliance. | ||
| 90 | |||
| 91 | 5. If you wish to incorporate parts of this program into other free | ||
| 92 | programs whose distribution conditions are different, write to the Free | ||
| 93 | Software Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not yet | ||
| 94 | worked out a simple rule that can be stated here, but we will often permit | ||
| 95 | this. We will be guided by the two goals of preserving the free status of | ||
| 96 | all derivatives of our free software and of promoting the sharing and reuse of | ||
| 97 | software. | ||
| 98 | |||
| 99 | |||
| 100 | In other words, you are welcome to use, share and improve this program. | ||
| 101 | You are forbidden to forbid anyone else to use, share and improve | ||
| 102 | what you give them. Help stamp out software-hoarding! */ | ||
| 103 | |||
| 104 | |||
| 105 | /* | ||
| 106 | * unexec.c - Convert a running program into an a.out file. | ||
| 107 | * | ||
| 108 | * Author: Spencer W. Thomas | ||
| 109 | * Computer Science Dept. | ||
| 110 | * University of Utah | ||
| 111 | * Date: Tue Mar 2 1982 | ||
| 112 | * Modified heavily since then. | ||
| 113 | * | ||
| 114 | * Synopsis: | ||
| 115 | * unexec (new_name, a_name, data_start, bss_start, entry_address) | ||
| 116 | * char *new_name, *a_name; | ||
| 117 | * unsigned data_start, bss_start, entry_address; | ||
| 118 | * | ||
| 119 | * Takes a snapshot of the program and makes an a.out format file in the | ||
| 120 | * file named by the string argument new_name. | ||
| 121 | * If a_name is non-NULL, the symbol table will be taken from the given file. | ||
| 122 | * On some machines, an existing a_name file is required. | ||
| 123 | * | ||
| 124 | * The boundaries within the a.out file may be adjusted with the data_start | ||
| 125 | * and bss_start arguments. Either or both may be given as 0 for defaults. | ||
| 126 | * | ||
| 127 | * Data_start gives the boundary between the text segment and the data | ||
| 128 | * segment of the program. The text segment can contain shared, read-only | ||
| 129 | * program code and literal data, while the data segment is always unshared | ||
| 130 | * and unprotected. Data_start gives the lowest unprotected address. | ||
| 131 | * The value you specify may be rounded down to a suitable boundary | ||
| 132 | * as required by the machine you are using. | ||
| 133 | * | ||
| 134 | * Specifying zero for data_start means the boundary between text and data | ||
| 135 | * should not be the same as when the program was loaded. | ||
| 136 | * If NO_REMAP is defined, the argument data_start is ignored and the | ||
| 137 | * segment boundaries are never changed. | ||
| 138 | * | ||
| 139 | * Bss_start indicates how much of the data segment is to be saved in the | ||
| 140 | * a.out file and restored when the program is executed. It gives the lowest | ||
| 141 | * unsaved address, and is rounded up to a page boundary. The default when 0 | ||
| 142 | * is given assumes that the entire data segment is to be stored, including | ||
| 143 | * the previous data and bss as well as any additional storage allocated with | ||
| 144 | * break (2). | ||
| 145 | * | ||
| 146 | * The new file is set up to start at entry_address. | ||
| 147 | * | ||
| 148 | * If you make improvements I'd like to get them too. | ||
| 149 | * harpo!utah-cs!thomas, thomas@Utah-20 | ||
| 150 | * | ||
| 151 | */ | ||
| 152 | |||
| 153 | /* Even more heavily modified by james@bigtex.cactus.org of Dell Computer Co. | ||
| 154 | * ELF support added. | ||
| 155 | * | ||
| 156 | * Basic theory: the data space of the running process needs to be | ||
| 157 | * dumped to the output file. Normally we would just enlarge the size | ||
| 158 | * of .data, scooting everything down. But we can't do that in ELF, | ||
| 159 | * because there is often something between the .data space and the | ||
| 160 | * .bss space. | ||
| 161 | * | ||
| 162 | * In the temacs dump below, notice that the Global Offset Table | ||
| 163 | * (.got) and the Dynamic link data (.dynamic) come between .data1 and | ||
| 164 | * .bss. It does not work to overlap .data with these fields. | ||
| 165 | * | ||
| 166 | * The solution is to create a new .data segment. This segment is | ||
| 167 | * filled with data from the current process. Since the contents of | ||
| 168 | * various sections refer to sections by index, the new .data segment | ||
| 169 | * is made the last in the table to avoid changing any existing index. | ||
| 170 | |||
| 171 | * This is an example of how the section headers are changed. "Addr" | ||
| 172 | * is a process virtual address. "Offset" is a file offset. | ||
| 173 | |||
| 174 | raid:/nfs/raid/src/dist-18.56/src> dump -h temacs | ||
| 175 | |||
| 176 | temacs: | ||
| 177 | |||
| 178 | **** SECTION HEADER TABLE **** | ||
| 179 | [No] Type Flags Addr Offset Size Name | ||
| 180 | Link Info Adralgn Entsize | ||
| 181 | |||
| 182 | [1] 1 2 0x80480d4 0xd4 0x13 .interp | ||
| 183 | 0 0 0x1 0 | ||
| 184 | |||
| 185 | [2] 5 2 0x80480e8 0xe8 0x388 .hash | ||
| 186 | 3 0 0x4 0x4 | ||
| 187 | |||
| 188 | [3] 11 2 0x8048470 0x470 0x7f0 .dynsym | ||
| 189 | 4 1 0x4 0x10 | ||
| 190 | |||
| 191 | [4] 3 2 0x8048c60 0xc60 0x3ad .dynstr | ||
| 192 | 0 0 0x1 0 | ||
| 193 | |||
| 194 | [5] 9 2 0x8049010 0x1010 0x338 .rel.plt | ||
| 195 | 3 7 0x4 0x8 | ||
| 196 | |||
| 197 | [6] 1 6 0x8049348 0x1348 0x3 .init | ||
| 198 | 0 0 0x4 0 | ||
| 199 | |||
| 200 | [7] 1 6 0x804934c 0x134c 0x680 .plt | ||
| 201 | 0 0 0x4 0x4 | ||
| 202 | |||
| 203 | [8] 1 6 0x80499cc 0x19cc 0x3c56f .text | ||
| 204 | 0 0 0x4 0 | ||
| 205 | |||
| 206 | [9] 1 6 0x8085f3c 0x3df3c 0x3 .fini | ||
| 207 | 0 0 0x4 0 | ||
| 208 | |||
| 209 | [10] 1 2 0x8085f40 0x3df40 0x69c .rodata | ||
| 210 | 0 0 0x4 0 | ||
| 211 | |||
| 212 | [11] 1 2 0x80865dc 0x3e5dc 0xd51 .rodata1 | ||
| 213 | 0 0 0x4 0 | ||
| 214 | |||
| 215 | [12] 1 3 0x8088330 0x3f330 0x20afc .data | ||
| 216 | 0 0 0x4 0 | ||
| 217 | |||
| 218 | [13] 1 3 0x80a8e2c 0x5fe2c 0x89d .data1 | ||
| 219 | 0 0 0x4 0 | ||
| 220 | |||
| 221 | [14] 1 3 0x80a96cc 0x606cc 0x1a8 .got | ||
| 222 | 0 0 0x4 0x4 | ||
| 223 | |||
| 224 | [15] 6 3 0x80a9874 0x60874 0x80 .dynamic | ||
| 225 | 4 0 0x4 0x8 | ||
| 226 | |||
| 227 | [16] 8 3 0x80a98f4 0x608f4 0x449c .bss | ||
| 228 | 0 0 0x4 0 | ||
| 229 | |||
| 230 | [17] 2 0 0 0x608f4 0x9b90 .symtab | ||
| 231 | 18 371 0x4 0x10 | ||
| 232 | |||
| 233 | [18] 3 0 0 0x6a484 0x8526 .strtab | ||
| 234 | 0 0 0x1 0 | ||
| 235 | |||
| 236 | [19] 3 0 0 0x729aa 0x93 .shstrtab | ||
| 237 | 0 0 0x1 0 | ||
| 238 | |||
| 239 | [20] 1 0 0 0x72a3d 0x68b7 .comment | ||
| 240 | 0 0 0x1 0 | ||
| 241 | |||
| 242 | raid:/nfs/raid/src/dist-18.56/src> dump -h xemacs | ||
| 243 | |||
| 244 | xemacs: | ||
| 245 | |||
| 246 | **** SECTION HEADER TABLE **** | ||
| 247 | [No] Type Flags Addr Offset Size Name | ||
| 248 | Link Info Adralgn Entsize | ||
| 249 | |||
| 250 | [1] 1 2 0x80480d4 0xd4 0x13 .interp | ||
| 251 | 0 0 0x1 0 | ||
| 252 | |||
| 253 | [2] 5 2 0x80480e8 0xe8 0x388 .hash | ||
| 254 | 3 0 0x4 0x4 | ||
| 255 | |||
| 256 | [3] 11 2 0x8048470 0x470 0x7f0 .dynsym | ||
| 257 | 4 1 0x4 0x10 | ||
| 258 | |||
| 259 | [4] 3 2 0x8048c60 0xc60 0x3ad .dynstr | ||
| 260 | 0 0 0x1 0 | ||
| 261 | |||
| 262 | [5] 9 2 0x8049010 0x1010 0x338 .rel.plt | ||
| 263 | 3 7 0x4 0x8 | ||
| 264 | |||
| 265 | [6] 1 6 0x8049348 0x1348 0x3 .init | ||
| 266 | 0 0 0x4 0 | ||
| 267 | |||
| 268 | [7] 1 6 0x804934c 0x134c 0x680 .plt | ||
| 269 | 0 0 0x4 0x4 | ||
| 270 | |||
| 271 | [8] 1 6 0x80499cc 0x19cc 0x3c56f .text | ||
| 272 | 0 0 0x4 0 | ||
| 273 | |||
| 274 | [9] 1 6 0x8085f3c 0x3df3c 0x3 .fini | ||
| 275 | 0 0 0x4 0 | ||
| 276 | |||
| 277 | [10] 1 2 0x8085f40 0x3df40 0x69c .rodata | ||
| 278 | 0 0 0x4 0 | ||
| 279 | |||
| 280 | [11] 1 2 0x80865dc 0x3e5dc 0xd51 .rodata1 | ||
| 281 | 0 0 0x4 0 | ||
| 282 | |||
| 283 | [12] 1 3 0x8088330 0x3f330 0x20afc .data | ||
| 284 | 0 0 0x4 0 | ||
| 285 | |||
| 286 | [13] 1 3 0x80a8e2c 0x5fe2c 0x89d .data1 | ||
| 287 | 0 0 0x4 0 | ||
| 288 | |||
| 289 | [14] 1 3 0x80a96cc 0x606cc 0x1a8 .got | ||
| 290 | 0 0 0x4 0x4 | ||
| 291 | |||
| 292 | [15] 6 3 0x80a9874 0x60874 0x80 .dynamic | ||
| 293 | 4 0 0x4 0x8 | ||
| 294 | |||
| 295 | [16] 8 3 0x80c6800 0x7d800 0 .bss | ||
| 296 | 0 0 0x4 0 | ||
| 297 | |||
| 298 | [17] 2 0 0 0x7d800 0x9b90 .symtab | ||
| 299 | 18 371 0x4 0x10 | ||
| 300 | |||
| 301 | [18] 3 0 0 0x87390 0x8526 .strtab | ||
| 302 | 0 0 0x1 0 | ||
| 303 | |||
| 304 | [19] 3 0 0 0x8f8b6 0x93 .shstrtab | ||
| 305 | 0 0 0x1 0 | ||
| 306 | |||
| 307 | [20] 1 0 0 0x8f949 0x68b7 .comment | ||
| 308 | 0 0 0x1 0 | ||
| 309 | |||
| 310 | [21] 1 3 0x80a98f4 0x608f4 0x1cf0c .data | ||
| 311 | 0 0 0x4 0 | ||
| 312 | |||
| 313 | * This is an example of how the file header is changed. "Shoff" is | ||
| 314 | * the section header offset within the file. Since that table is | ||
| 315 | * after the new .data section, it is moved. "Shnum" is the number of | ||
| 316 | * sections, which we increment. | ||
| 317 | * | ||
| 318 | * "Phoff" is the file offset to the program header. "Phentsize" and | ||
| 319 | * "Shentsz" are the program and section header entries sizes respectively. | ||
| 320 | * These can be larger than the apparent struct sizes. | ||
| 321 | |||
| 322 | raid:/nfs/raid/src/dist-18.56/src> dump -f temacs | ||
| 323 | |||
| 324 | temacs: | ||
| 325 | |||
| 326 | **** ELF HEADER **** | ||
| 327 | Class Data Type Machine Version | ||
| 328 | Entry Phoff Shoff Flags Ehsize | ||
| 329 | Phentsize Phnum Shentsz Shnum Shstrndx | ||
| 330 | |||
| 331 | 1 1 2 3 1 | ||
| 332 | 0x80499cc 0x34 0x792f4 0 0x34 | ||
| 333 | 0x20 5 0x28 21 19 | ||
| 334 | |||
| 335 | raid:/nfs/raid/src/dist-18.56/src> dump -f xemacs | ||
| 336 | |||
| 337 | xemacs: | ||
| 338 | |||
| 339 | **** ELF HEADER **** | ||
| 340 | Class Data Type Machine Version | ||
| 341 | Entry Phoff Shoff Flags Ehsize | ||
| 342 | Phentsize Phnum Shentsz Shnum Shstrndx | ||
| 343 | |||
| 344 | 1 1 2 3 1 | ||
| 345 | 0x80499cc 0x34 0x96200 0 0x34 | ||
| 346 | 0x20 5 0x28 22 19 | ||
| 347 | |||
| 348 | * These are the program headers. "Offset" is the file offset to the | ||
| 349 | * segment. "Vaddr" is the memory load address. "Filesz" is the | ||
| 350 | * segment size as it appears in the file, and "Memsz" is the size in | ||
| 351 | * memory. Below, the third segment is the code and the fourth is the | ||
| 352 | * data: the difference between Filesz and Memsz is .bss | ||
| 353 | |||
| 354 | raid:/nfs/raid/src/dist-18.56/src> dump -o temacs | ||
| 355 | |||
| 356 | temacs: | ||
| 357 | ***** PROGRAM EXECUTION HEADER ***** | ||
| 358 | Type Offset Vaddr Paddr | ||
| 359 | Filesz Memsz Flags Align | ||
| 360 | |||
| 361 | 6 0x34 0x8048034 0 | ||
| 362 | 0xa0 0xa0 5 0 | ||
| 363 | |||
| 364 | 3 0xd4 0 0 | ||
| 365 | 0x13 0 4 0 | ||
| 366 | |||
| 367 | 1 0x34 0x8048034 0 | ||
| 368 | 0x3f2f9 0x3f2f9 5 0x1000 | ||
| 369 | |||
| 370 | 1 0x3f330 0x8088330 0 | ||
| 371 | 0x215c4 0x25a60 7 0x1000 | ||
| 372 | |||
| 373 | 2 0x60874 0x80a9874 0 | ||
| 374 | 0x80 0 7 0 | ||
| 375 | |||
| 376 | raid:/nfs/raid/src/dist-18.56/src> dump -o xemacs | ||
| 377 | |||
| 378 | xemacs: | ||
| 379 | ***** PROGRAM EXECUTION HEADER ***** | ||
| 380 | Type Offset Vaddr Paddr | ||
| 381 | Filesz Memsz Flags Align | ||
| 382 | |||
| 383 | 6 0x34 0x8048034 0 | ||
| 384 | 0xa0 0xa0 5 0 | ||
| 385 | |||
| 386 | 3 0xd4 0 0 | ||
| 387 | 0x13 0 4 0 | ||
| 388 | |||
| 389 | 1 0x34 0x8048034 0 | ||
| 390 | 0x3f2f9 0x3f2f9 5 0x1000 | ||
| 391 | |||
| 392 | 1 0x3f330 0x8088330 0 | ||
| 393 | 0x3e4d0 0x3e4d0 7 0x1000 | ||
| 394 | |||
| 395 | 2 0x60874 0x80a9874 0 | ||
| 396 | 0x80 0 7 0 | ||
| 397 | |||
| 398 | |||
| 399 | */ | ||
| 400 | |||
| 401 | #include <sys/types.h> | ||
| 402 | #include <stdio.h> | ||
| 403 | #include <sys/stat.h> | ||
| 404 | #include <memory.h> | ||
| 405 | #include <string.h> | ||
| 406 | #include <errno.h> | ||
| 407 | #include <unistd.h> | ||
| 408 | #include <fcntl.h> | ||
| 409 | #include <elf.h> | ||
| 410 | #include <sys/mman.h> | ||
| 411 | |||
| 412 | #ifndef emacs | ||
| 413 | #define fatal(a, b, c) fprintf(stderr, a, b, c), exit(1) | ||
| 414 | #else | ||
| 415 | extern void fatal(char *, ...); | ||
| 416 | #endif | ||
| 417 | |||
| 418 | /* Get the address of a particular section or program header entry, | ||
| 419 | * accounting for the size of the entries. | ||
| 420 | */ | ||
| 421 | |||
| 422 | #define OLD_SECTION_H(n) \ | ||
| 423 | (*(Elf32_Shdr *) ((byte *) old_section_h + old_file_h->e_shentsize * (n))) | ||
| 424 | #define NEW_SECTION_H(n) \ | ||
| 425 | (*(Elf32_Shdr *) ((byte *) new_section_h + new_file_h->e_shentsize * (n))) | ||
| 426 | #define OLD_PROGRAM_H(n) \ | ||
| 427 | (*(Elf32_Phdr *) ((byte *) old_program_h + old_file_h->e_phentsize * (n))) | ||
| 428 | #define NEW_PROGRAM_H(n) \ | ||
| 429 | (*(Elf32_Phdr *) ((byte *) new_program_h + new_file_h->e_phentsize * (n))) | ||
| 430 | |||
| 431 | typedef unsigned char byte; | ||
| 432 | |||
| 433 | /* **************************************************************** | ||
| 434 | * unexec | ||
| 435 | * | ||
| 436 | * driving logic. | ||
| 437 | * | ||
| 438 | * In ELF, this works by replacing the old .bss section with a new | ||
| 439 | * .data section, and inserting an empty .bss immediately afterwards. | ||
| 440 | * | ||
| 441 | */ | ||
| 442 | void | ||
| 443 | unexec (new_name, old_name, data_start, bss_start, entry_address) | ||
| 444 | char *new_name, *old_name; | ||
| 445 | unsigned data_start, bss_start, entry_address; | ||
| 446 | { | ||
| 447 | extern unsigned int bss_end; | ||
| 448 | int new_file, old_file, new_file_size; | ||
| 449 | |||
| 450 | /* Pointers to the base of the image of the two files. */ | ||
| 451 | caddr_t old_base, new_base; | ||
| 452 | |||
| 453 | /* Pointers to the file, program and section headers for the old and new | ||
| 454 | * files. | ||
| 455 | */ | ||
| 456 | Elf32_Ehdr *old_file_h, *new_file_h; | ||
| 457 | Elf32_Phdr *old_program_h, *new_program_h; | ||
| 458 | Elf32_Shdr *old_section_h, *new_section_h; | ||
| 459 | |||
| 460 | /* Point to the section name table in the old file */ | ||
| 461 | char *old_section_names; | ||
| 462 | |||
| 463 | Elf32_Addr old_bss_addr, new_bss_addr; | ||
| 464 | Elf32_Word old_bss_size, new_data2_size; | ||
| 465 | Elf32_Off new_data2_offset; | ||
| 466 | Elf32_Addr new_data2_addr; | ||
| 467 | |||
| 468 | int n, old_bss_index, old_data_index, new_data2_index; | ||
| 469 | struct stat stat_buf; | ||
| 470 | |||
| 471 | /* Open the old file & map it into the address space. */ | ||
| 472 | |||
| 473 | old_file = open (old_name, O_RDONLY); | ||
| 474 | |||
| 475 | if (old_file < 0) | ||
| 476 | fatal ("Can't open %s for reading: errno %d\n", old_name, errno); | ||
| 477 | |||
| 478 | if (fstat (old_file, &stat_buf) == -1) | ||
| 479 | fatal ("Can't fstat(%s): errno %d\n", old_name, errno); | ||
| 480 | |||
| 481 | old_base = mmap (0, stat_buf.st_size, PROT_READ, MAP_SHARED, old_file, 0); | ||
| 482 | |||
| 483 | if (old_base == (caddr_t) -1) | ||
| 484 | fatal ("Can't mmap(%s): errno %d\n", old_name, errno); | ||
| 485 | |||
| 486 | #ifdef DEBUG | ||
| 487 | fprintf (stderr, "mmap(%s, %x) -> %x\n", old_name, stat_buf.st_size, | ||
| 488 | old_base); | ||
| 489 | #endif | ||
| 490 | |||
| 491 | /* Get pointers to headers & section names */ | ||
| 492 | |||
| 493 | old_file_h = (Elf32_Ehdr *) old_base; | ||
| 494 | old_program_h = (Elf32_Phdr *) ((byte *) old_base + old_file_h->e_phoff); | ||
| 495 | old_section_h = (Elf32_Shdr *) ((byte *) old_base + old_file_h->e_shoff); | ||
| 496 | old_section_names = (char *) old_base | ||
| 497 | + OLD_SECTION_H(old_file_h->e_shstrndx).sh_offset; | ||
| 498 | |||
| 499 | /* Find the old .bss section. Figure out parameters of the new | ||
| 500 | * data2 and bss sections. | ||
| 501 | */ | ||
| 502 | |||
| 503 | for (old_bss_index = 1; old_bss_index < old_file_h->e_shnum; old_bss_index++) | ||
| 504 | { | ||
| 505 | #ifdef DEBUG | ||
| 506 | fprintf (stderr, "Looking for .bss - found %s\n", | ||
| 507 | old_section_names + OLD_SECTION_H(old_bss_index).sh_name); | ||
| 508 | #endif | ||
| 509 | if (!strcmp (old_section_names + OLD_SECTION_H(old_bss_index).sh_name, | ||
| 510 | ".bss")) | ||
| 511 | break; | ||
| 512 | } | ||
| 513 | if (old_bss_index == old_file_h->e_shnum) | ||
| 514 | fatal ("Can't find .bss in %s.\n", old_name, 0); | ||
| 515 | |||
| 516 | old_bss_addr = OLD_SECTION_H(old_bss_index).sh_addr; | ||
| 517 | old_bss_size = OLD_SECTION_H(old_bss_index).sh_size; | ||
| 518 | #if defined(emacs) || !defined(DEBUG) | ||
| 519 | bss_end = (unsigned int) sbrk (0); | ||
| 520 | new_bss_addr = (Elf32_Addr) bss_end; | ||
| 521 | #else | ||
| 522 | new_bss_addr = old_bss_addr + old_bss_size + 0x1234; | ||
| 523 | #endif | ||
| 524 | new_data2_addr = old_bss_addr; | ||
| 525 | new_data2_size = new_bss_addr - old_bss_addr; | ||
| 526 | new_data2_offset = OLD_SECTION_H(old_bss_index).sh_offset; | ||
| 527 | |||
| 528 | #ifdef DEBUG | ||
| 529 | fprintf (stderr, "old_bss_index %d\n", old_bss_index); | ||
| 530 | fprintf (stderr, "old_bss_addr %x\n", old_bss_addr); | ||
| 531 | fprintf (stderr, "old_bss_size %x\n", old_bss_size); | ||
| 532 | fprintf (stderr, "new_bss_addr %x\n", new_bss_addr); | ||
| 533 | fprintf (stderr, "new_data2_addr %x\n", new_data2_addr); | ||
| 534 | fprintf (stderr, "new_data2_size %x\n", new_data2_size); | ||
| 535 | fprintf (stderr, "new_data2_offset %x\n", new_data2_offset); | ||
| 536 | #endif | ||
| 537 | |||
| 538 | if ((unsigned) new_bss_addr < (unsigned) old_bss_addr + old_bss_size) | ||
| 539 | fatal (".bss shrank when undumping???\n", 0, 0); | ||
| 540 | |||
| 541 | /* Set the output file to the right size and mmap(2) it. Set | ||
| 542 | * pointers to various interesting objects. stat_buf still has | ||
| 543 | * old_file data. | ||
| 544 | */ | ||
| 545 | |||
| 546 | new_file = open (new_name, O_RDWR | O_CREAT, 0666); | ||
| 547 | if (new_file < 0) | ||
| 548 | fatal ("Can't creat(%s): errno %d\n", new_name, errno); | ||
| 549 | |||
| 550 | new_file_size = stat_buf.st_size + old_file_h->e_shentsize + new_data2_size; | ||
| 551 | |||
| 552 | if (ftruncate (new_file, new_file_size)) | ||
| 553 | fatal ("Can't ftruncate(%s): errno %d\n", new_name, errno); | ||
| 554 | |||
| 555 | new_base = mmap (0, new_file_size, PROT_READ | PROT_WRITE, MAP_SHARED, | ||
| 556 | new_file, 0); | ||
| 557 | |||
| 558 | if (new_base == (caddr_t) -1) | ||
| 559 | fatal ("Can't mmap(%s): errno %d\n", new_name, errno); | ||
| 560 | |||
| 561 | new_file_h = (Elf32_Ehdr *) new_base; | ||
| 562 | new_program_h = (Elf32_Phdr *) ((byte *) new_base + old_file_h->e_phoff); | ||
| 563 | new_section_h = (Elf32_Shdr *) | ||
| 564 | ((byte *) new_base + old_file_h->e_shoff + new_data2_size); | ||
| 565 | |||
| 566 | /* Make our new file, program and section headers as copies of the | ||
| 567 | * originals. | ||
| 568 | */ | ||
| 569 | |||
| 570 | memcpy (new_file_h, old_file_h, old_file_h->e_ehsize); | ||
| 571 | memcpy (new_program_h, old_program_h, | ||
| 572 | old_file_h->e_phnum * old_file_h->e_phentsize); | ||
| 573 | memcpy (new_section_h, old_section_h, | ||
| 574 | old_file_h->e_shnum * old_file_h->e_shentsize); | ||
| 575 | |||
| 576 | /* Fix up file header. We'll add one section. Section header is | ||
| 577 | * further away now. | ||
| 578 | */ | ||
| 579 | |||
| 580 | new_file_h->e_shoff += new_data2_size; | ||
| 581 | new_file_h->e_shnum += 1; | ||
| 582 | |||
| 583 | #ifdef DEBUG | ||
| 584 | fprintf (stderr, "Old section offset %x\n", old_file_h->e_shoff); | ||
| 585 | fprintf (stderr, "Old section count %d\n", old_file_h->e_shnum); | ||
| 586 | fprintf (stderr, "New section offset %x\n", new_file_h->e_shoff); | ||
| 587 | fprintf (stderr, "New section count %d\n", new_file_h->e_shnum); | ||
| 588 | #endif | ||
| 589 | |||
| 590 | /* Fix up a new program header. Extend the writable data segment so | ||
| 591 | * that the bss area is covered too. Find that segment by looking | ||
| 592 | * for a segment that ends just before the .bss area. Make sure | ||
| 593 | * that no segments are above the new .data2. Put a loop at the end | ||
| 594 | * to adjust the offset and address of any segment that is above | ||
| 595 | * data2, just in case we decide to allow this later. | ||
| 596 | */ | ||
| 597 | |||
| 598 | for (n = new_file_h->e_phnum - 1; n >= 0; n--) | ||
| 599 | { | ||
| 600 | if (NEW_PROGRAM_H(n).p_vaddr + NEW_PROGRAM_H(n).p_filesz > old_bss_addr) | ||
| 601 | fatal ("Program segment above .bss in %s\n", old_name, 0); | ||
| 602 | |||
| 603 | if (NEW_PROGRAM_H(n).p_type == PT_LOAD | ||
| 604 | && (NEW_PROGRAM_H(n).p_vaddr + NEW_PROGRAM_H(n).p_filesz | ||
| 605 | == old_bss_addr)) | ||
| 606 | break; | ||
| 607 | } | ||
| 608 | if (n < 0) | ||
| 609 | fatal ("Couldn't find segment next to .bss in %s\n", old_name, 0); | ||
| 610 | |||
| 611 | NEW_PROGRAM_H(n).p_filesz += new_data2_size; | ||
| 612 | NEW_PROGRAM_H(n).p_memsz = NEW_PROGRAM_H(n).p_filesz; | ||
| 613 | |||
| 614 | #if 0 /* Maybe allow section after data2 - does this ever happen? */ | ||
| 615 | for (n = new_file_h->e_phnum - 1; n >= 0; n--) | ||
| 616 | { | ||
| 617 | if (NEW_PROGRAM_H(n).p_vaddr | ||
| 618 | && NEW_PROGRAM_H(n).p_vaddr >= new_data2_addr) | ||
| 619 | NEW_PROGRAM_H(n).p_vaddr += new_data2_size - old_bss_size; | ||
| 620 | |||
| 621 | if (NEW_PROGRAM_H(n).p_offset >= new_data2_offset) | ||
| 622 | NEW_PROGRAM_H(n).p_offset += new_data2_size; | ||
| 623 | } | ||
| 624 | #endif | ||
| 625 | |||
| 626 | /* Fix up section headers based on new .data2 section. Any section | ||
| 627 | * whose offset or virtual address is after the new .data2 section | ||
| 628 | * gets its value adjusted. .bss size becomes zero and new address | ||
| 629 | * is set. data2 section header gets added by copying the existing | ||
| 630 | * .data header and modifying the offset, address and size. | ||
| 631 | */ | ||
| 632 | |||
| 633 | for (n = 1; n < new_file_h->e_shnum; n++) | ||
| 634 | { | ||
| 635 | if (NEW_SECTION_H(n).sh_offset >= new_data2_offset) | ||
| 636 | NEW_SECTION_H(n).sh_offset += new_data2_size; | ||
| 637 | |||
| 638 | if (NEW_SECTION_H(n).sh_addr | ||
| 639 | && NEW_SECTION_H(n).sh_addr >= new_data2_addr) | ||
| 640 | NEW_SECTION_H(n).sh_addr += new_data2_size - old_bss_size; | ||
| 641 | } | ||
| 642 | |||
| 643 | new_data2_index = old_file_h->e_shnum; | ||
| 644 | |||
| 645 | for (old_data_index = 1; old_data_index < old_file_h->e_shnum; | ||
| 646 | old_data_index++) | ||
| 647 | if (!strcmp (old_section_names + OLD_SECTION_H(old_data_index).sh_name, | ||
| 648 | ".data")) | ||
| 649 | break; | ||
| 650 | if (old_data_index == old_file_h->e_shnum) | ||
| 651 | fatal ("Can't find .data in %s.\n", old_name, 0); | ||
| 652 | |||
| 653 | memcpy (&NEW_SECTION_H(new_data2_index), &OLD_SECTION_H(old_data_index), | ||
| 654 | new_file_h->e_shentsize); | ||
| 655 | |||
| 656 | NEW_SECTION_H(new_data2_index).sh_addr = new_data2_addr; | ||
| 657 | NEW_SECTION_H(new_data2_index).sh_offset = new_data2_offset; | ||
| 658 | NEW_SECTION_H(new_data2_index).sh_size = new_data2_size; | ||
| 659 | |||
| 660 | NEW_SECTION_H(old_bss_index).sh_size = 0; | ||
| 661 | NEW_SECTION_H(old_bss_index).sh_addr = new_data2_addr + new_data2_size; | ||
| 662 | |||
| 663 | /* Write out the sections. .data and .data1 (and data2, called | ||
| 664 | * ".data" in the strings table) get copied from the current process | ||
| 665 | * instead of the old file. | ||
| 666 | */ | ||
| 667 | |||
| 668 | for (n = new_file_h->e_shnum - 1; n; n--) | ||
| 669 | { | ||
| 670 | caddr_t src; | ||
| 671 | |||
| 672 | if (NEW_SECTION_H(n).sh_type == SHT_NULL | ||
| 673 | || NEW_SECTION_H(n).sh_type == SHT_NOBITS) | ||
| 674 | continue; | ||
| 675 | |||
| 676 | if (!strcmp (old_section_names + NEW_SECTION_H(n).sh_name, ".data") | ||
| 677 | || !strcmp ((old_section_names + NEW_SECTION_H(n).sh_name), | ||
| 678 | ".data1")) | ||
| 679 | src = (caddr_t) NEW_SECTION_H(n).sh_addr; | ||
| 680 | else | ||
| 681 | src = old_base + OLD_SECTION_H(n).sh_offset; | ||
| 682 | |||
| 683 | memcpy (NEW_SECTION_H(n).sh_offset + new_base, src, | ||
| 684 | NEW_SECTION_H(n).sh_size); | ||
| 685 | } | ||
| 686 | |||
| 687 | /* Close the files and make the new file executable */ | ||
| 688 | |||
| 689 | if (close (old_file)) | ||
| 690 | fatal ("Can't close(%s): errno %d\n", old_name, errno); | ||
| 691 | |||
| 692 | if (close (new_file)) | ||
| 693 | fatal ("Can't close(%s): errno %d\n", new_name, errno); | ||
| 694 | |||
| 695 | if (stat (new_name, &stat_buf) == -1) | ||
| 696 | fatal ("Can't stat(%s): errno %d\n", new_name, errno); | ||
| 697 | |||
| 698 | n = umask (777); | ||
| 699 | umask (n); | ||
| 700 | stat_buf.st_mode |= 0111 & ~n; | ||
| 701 | if (chmod (new_name, stat_buf.st_mode) == -1) | ||
| 702 | fatal ("Can't chmod(%s): errno %d\n", new_name, errno); | ||
| 703 | } | ||
diff --git a/src/unexenix.c b/src/unexenix.c new file mode 100644 index 00000000000..ea6cd7d5c20 --- /dev/null +++ b/src/unexenix.c | |||
| @@ -0,0 +1,262 @@ | |||
| 1 | /* Unexec for Xenix. | ||
| 2 | Note that the GNU project considers support for Xenix operation | ||
| 3 | a peripheral activity which should not be allowed to divert effort | ||
| 4 | from development of the GNU system. Changes in this code will be | ||
| 5 | installed when Xenix users send them in, but aside from that | ||
| 6 | we don't plan to think about it, or about whether other Emacs | ||
| 7 | maintenance might break it. | ||
| 8 | |||
| 9 | Copyright (C) 1988 Free Software Foundation, Inc. | ||
| 10 | |||
| 11 | This file is part of GNU Emacs. | ||
| 12 | |||
| 13 | GNU Emacs is free software; you can redistribute it and/or modify | ||
| 14 | it under the terms of the GNU General Public License as published by | ||
| 15 | the Free Software Foundation; either version 1, or (at your option) | ||
| 16 | any later version. | ||
| 17 | |||
| 18 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 19 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 21 | GNU General Public License for more details. | ||
| 22 | |||
| 23 | You should have received a copy of the GNU General Public License | ||
| 24 | along with GNU Emacs; see the file COPYING. If not, write to | ||
| 25 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
| 26 | |||
| 27 | |||
| 28 | |||
| 29 | /* | ||
| 30 | On 80386 Xenix, segmentation screws prevent us from modifying the text | ||
| 31 | segment at all. We basically just plug a new value for "data segment | ||
| 32 | size" into the countless headers and copy the other records straight | ||
| 33 | through. The data segment is ORG'ed at the xs_rbase value of the data | ||
| 34 | segment's xseg record (always @ 0x1880000, thanks to the "sophisticated | ||
| 35 | memory management hardware" of the chip) and extends to sbrk(0), exactly. | ||
| 36 | This code is afraid to malloc (should it be?), and alloca has to be the | ||
| 37 | wimpy, malloc-based version; consequently, data is usually copied in | ||
| 38 | smallish chunks. | ||
| 39 | |||
| 40 | gb@entity.com | ||
| 41 | */ | ||
| 42 | |||
| 43 | #include "config.h" | ||
| 44 | #include <sys/types.h> | ||
| 45 | #include <fcntl.h> | ||
| 46 | #include <sys/file.h> | ||
| 47 | #include <sys/stat.h> | ||
| 48 | #include <stdio.h> | ||
| 49 | #include <varargs.h> | ||
| 50 | #include <a.out.h> | ||
| 51 | |||
| 52 | static void fatal_unexec (); | ||
| 53 | |||
| 54 | #define READ(_fd, _buffer, _size, _error_message, _error_arg) \ | ||
| 55 | errno = EEOF; \ | ||
| 56 | if (read(_fd, _buffer, _size) != _size) \ | ||
| 57 | fatal_unexec(_error_message, _error_arg); | ||
| 58 | |||
| 59 | #define WRITE(_fd, _buffer, _size, _error_message, _error_arg) \ | ||
| 60 | if (write(_fd, _buffer, _size) != _size) \ | ||
| 61 | fatal_unexec(_error_message, _error_arg); | ||
| 62 | |||
| 63 | #define SEEK(_fd, _position, _error_message, _error_arg) \ | ||
| 64 | errno = EEOF; \ | ||
| 65 | if (lseek(_fd, _position, L_SET) != _position) \ | ||
| 66 | fatal_unexec(_error_message, _error_arg); | ||
| 67 | |||
| 68 | extern int errno; | ||
| 69 | extern int sys_nerr; | ||
| 70 | extern char *sys_errlist[]; | ||
| 71 | #define EEOF -1 | ||
| 72 | |||
| 73 | #ifndef L_SET | ||
| 74 | #define L_SET 0 | ||
| 75 | #endif | ||
| 76 | |||
| 77 | /* Should check the magic number of the old executable; | ||
| 78 | not yet written. */ | ||
| 79 | check_exec (x) | ||
| 80 | struct xexec *x; | ||
| 81 | { | ||
| 82 | } | ||
| 83 | |||
| 84 | |||
| 85 | unexec (new_name, a_name, data_start, bss_start, entry_address) | ||
| 86 | char *new_name, *a_name; | ||
| 87 | unsigned data_start, bss_start, entry_address; | ||
| 88 | { | ||
| 89 | char *sbrk (), *datalim = sbrk (0), *data_org; | ||
| 90 | long segpos, textseen, textpos, textlen, datapos, datadiff, datalen; | ||
| 91 | |||
| 92 | struct xexec u_xexec, /* a.out header */ | ||
| 93 | *u_xexecp = &u_xexec; | ||
| 94 | struct xext u_xext, /* extended header */ | ||
| 95 | *u_xextp = &u_xext; | ||
| 96 | struct xseg u_xseg, /* segment table entry */ | ||
| 97 | *u_xsegp = &u_xseg; | ||
| 98 | int i, nsegs, isdata = 0, infd, outfd; | ||
| 99 | |||
| 100 | infd = open (a_name, O_RDONLY, 0); | ||
| 101 | if (infd < 0) fatal_unexec ("opening %s", a_name); | ||
| 102 | |||
| 103 | outfd = creat (new_name, 0666); | ||
| 104 | if (outfd < 0) fatal_unexec ("creating %s", new_name); | ||
| 105 | |||
| 106 | READ (infd, u_xexecp, sizeof (struct xexec), | ||
| 107 | "error reading %s", a_name); | ||
| 108 | check_exec (u_xexecp); | ||
| 109 | READ (infd, u_xextp, sizeof (struct xext), | ||
| 110 | "error reading %s", a_name); | ||
| 111 | segpos = u_xextp->xe_segpos; | ||
| 112 | nsegs = u_xextp->xe_segsize / sizeof (struct xseg); | ||
| 113 | SEEK (infd, segpos, "seek error on %s", a_name); | ||
| 114 | for (i = 0; i < nsegs; i ++) | ||
| 115 | { | ||
| 116 | READ (infd, u_xsegp, sizeof (struct xseg), | ||
| 117 | "error reading %s", a_name); | ||
| 118 | switch (u_xsegp->xs_type) | ||
| 119 | { | ||
| 120 | case XS_TTEXT: | ||
| 121 | { | ||
| 122 | if (i == 0) | ||
| 123 | { | ||
| 124 | textpos = u_xsegp->xs_filpos; | ||
| 125 | textlen = u_xsegp->xs_psize; | ||
| 126 | break; | ||
| 127 | } | ||
| 128 | fatal_unexec ("invalid text segment in %s", a_name); | ||
| 129 | } | ||
| 130 | case XS_TDATA: | ||
| 131 | { | ||
| 132 | if (i == 1) | ||
| 133 | { | ||
| 134 | datapos = u_xsegp->xs_filpos; | ||
| 135 | datalen = datalim - (data_org = (char *)(u_xsegp->xs_rbase)); | ||
| 136 | datadiff = datalen - u_xsegp->xs_psize; | ||
| 137 | break; | ||
| 138 | } | ||
| 139 | fatal_unexec ("invalid data segment in %s", a_name); | ||
| 140 | } | ||
| 141 | default: | ||
| 142 | { | ||
| 143 | if (i > 1) break; | ||
| 144 | fatal_unexec ("invalid segment record in %s", a_name); | ||
| 145 | } | ||
| 146 | } | ||
| 147 | } | ||
| 148 | u_xexecp->x_data = datalen; | ||
| 149 | u_xexecp->x_bss = 0; | ||
| 150 | WRITE (outfd, u_xexecp, sizeof (struct xexec), | ||
| 151 | "error writing %s", new_name); | ||
| 152 | WRITE (outfd, u_xextp, sizeof (struct xext), | ||
| 153 | "error writing %s", new_name); | ||
| 154 | SEEK (infd, segpos, "seek error on %s", a_name); | ||
| 155 | SEEK (outfd, segpos, "seek error on %s", new_name); | ||
| 156 | |||
| 157 | /* Copy the text segment record verbatim. */ | ||
| 158 | |||
| 159 | copyrec (infd, outfd, sizeof (struct xseg), a_name, new_name); | ||
| 160 | |||
| 161 | /* Read, modify, write the data segment record. */ | ||
| 162 | |||
| 163 | READ (infd, u_xsegp, sizeof (struct xseg), | ||
| 164 | "error reading %s", a_name); | ||
| 165 | u_xsegp->xs_psize = u_xsegp->xs_vsize = datalen; | ||
| 166 | u_xsegp->xs_attr &= (~XS_AITER & ~XS_ABSS); | ||
| 167 | WRITE (outfd, u_xsegp, sizeof (struct xseg), | ||
| 168 | "error writing %s", new_name); | ||
| 169 | |||
| 170 | /* Now copy any additional segment records, adjusting their | ||
| 171 | file position field */ | ||
| 172 | |||
| 173 | for (i = 2; i < nsegs; i++) | ||
| 174 | { | ||
| 175 | READ (infd, u_xsegp, sizeof (struct xseg), | ||
| 176 | "error reading %s", a_name); | ||
| 177 | u_xsegp->xs_filpos += datadiff; | ||
| 178 | WRITE (outfd, u_xsegp, sizeof (struct xseg), | ||
| 179 | "error writing %s", new_name); | ||
| 180 | } | ||
| 181 | |||
| 182 | SEEK (infd, textpos, "seek error on %s", a_name); | ||
| 183 | SEEK (outfd, textpos, "seek error on %s", new_name); | ||
| 184 | copyrec (infd, outfd, textlen, a_name, new_name); | ||
| 185 | |||
| 186 | SEEK (outfd, datapos, "seek error on %s", new_name); | ||
| 187 | WRITE (outfd, data_org, datalen, | ||
| 188 | "write error on %s", new_name); | ||
| 189 | |||
| 190 | for (i = 2, segpos += (2 * sizeof (struct xseg)); | ||
| 191 | i < nsegs; | ||
| 192 | i++, segpos += sizeof (struct xseg)) | ||
| 193 | { | ||
| 194 | SEEK (infd, segpos, "seek error on %s", a_name); | ||
| 195 | READ (infd, u_xsegp, sizeof (struct xseg), | ||
| 196 | "read error on %s", a_name); | ||
| 197 | SEEK (infd, u_xsegp->xs_filpos, "seek error on %s", a_name); | ||
| 198 | /* We should be at eof in the output file here, but we must seek | ||
| 199 | because the xs_filpos and xs_psize fields in symbol table | ||
| 200 | segments are inconsistent. */ | ||
| 201 | SEEK (outfd, u_xsegp->xs_filpos + datadiff, "seek error on %s", new_name); | ||
| 202 | copyrec (infd, outfd, u_xsegp->xs_psize, a_name, new_name); | ||
| 203 | } | ||
| 204 | close (infd); | ||
| 205 | close (outfd); | ||
| 206 | mark_x (new_name); | ||
| 207 | return 0; | ||
| 208 | } | ||
| 209 | |||
| 210 | copyrec (infd, outfd, len, in_name, out_name) | ||
| 211 | int infd, outfd, len; | ||
| 212 | char *in_name, *out_name; | ||
| 213 | { | ||
| 214 | char buf[BUFSIZ]; | ||
| 215 | int chunk; | ||
| 216 | |||
| 217 | while (len) | ||
| 218 | { | ||
| 219 | chunk = BUFSIZ; | ||
| 220 | if (chunk > len) | ||
| 221 | chunk = len; | ||
| 222 | READ (infd, buf, chunk, "error reading %s", in_name); | ||
| 223 | WRITE (outfd, buf, chunk, "error writing %s", out_name); | ||
| 224 | len -= chunk; | ||
| 225 | } | ||
| 226 | } | ||
| 227 | |||
| 228 | /* | ||
| 229 | * mark_x | ||
| 230 | * | ||
| 231 | * After succesfully building the new a.out, mark it executable | ||
| 232 | */ | ||
| 233 | static | ||
| 234 | mark_x (name) | ||
| 235 | char *name; | ||
| 236 | { | ||
| 237 | struct stat sbuf; | ||
| 238 | int um = umask (777); | ||
| 239 | umask (um); | ||
| 240 | if (stat (name, &sbuf) < 0) | ||
| 241 | fatal_unexec ("getting protection on %s", name); | ||
| 242 | sbuf.st_mode |= 0111 & ~um; | ||
| 243 | if (chmod (name, sbuf.st_mode) < 0) | ||
| 244 | fatal_unexec ("setting protection on %s", name); | ||
| 245 | } | ||
| 246 | |||
| 247 | static void | ||
| 248 | fatal_unexec (s, va_alist) | ||
| 249 | va_dcl | ||
| 250 | { | ||
| 251 | va_list ap; | ||
| 252 | if (errno == EEOF) | ||
| 253 | fputs ("unexec: unexpected end of file, ", stderr); | ||
| 254 | else if (errno < sys_nerr) | ||
| 255 | fprintf (stderr, "unexec: %s, ", sys_errlist[errno]); | ||
| 256 | else | ||
| 257 | fprintf (stderr, "unexec: error code %d, ", errno); | ||
| 258 | va_start (ap); | ||
| 259 | _doprnt (s, ap, stderr); | ||
| 260 | fputs (".\n", stderr); | ||
| 261 | exit (1); | ||
| 262 | } | ||
diff --git a/src/unexhp9k800.c b/src/unexhp9k800.c index 259b9318514..8d34a3a3d7a 100644 --- a/src/unexhp9k800.c +++ b/src/unexhp9k800.c | |||
| @@ -60,6 +60,7 @@ unexec(new_name, old_name, new_end_of_text, dummy1, dummy2) | |||
| 60 | int old_size, new_size; | 60 | int old_size, new_size; |
| 61 | struct header hdr; | 61 | struct header hdr; |
| 62 | struct som_exec_auxhdr auxhdr; | 62 | struct som_exec_auxhdr auxhdr; |
| 63 | long i; | ||
| 63 | 64 | ||
| 64 | /* For the greatest flexibility, should create a temporary file in | 65 | /* For the greatest flexibility, should create a temporary file in |
| 65 | the same directory as the new file. When everything is complete, | 66 | the same directory as the new file. When everything is complete, |
| @@ -81,7 +82,10 @@ unexec(new_name, old_name, new_end_of_text, dummy1, dummy2) | |||
| 81 | 82 | ||
| 82 | /* Decide how large the new and old data areas are */ | 83 | /* Decide how large the new and old data areas are */ |
| 83 | old_size = auxhdr.exec_dsize; | 84 | old_size = auxhdr.exec_dsize; |
| 84 | new_size = sbrk(0) - auxhdr.exec_dmem; | 85 | /* I suspect these two statements are separate |
| 86 | to avoid a compiler bug in hpux version 8. */ | ||
| 87 | i = sbrk (0); | ||
| 88 | new_size = i - auxhdr.exec_dmem; | ||
| 85 | 89 | ||
| 86 | /* Copy the old file to the new, up to the data space */ | 90 | /* Copy the old file to the new, up to the data space */ |
| 87 | lseek(old, 0, 0); | 91 | lseek(old, 0, 0); |
diff --git a/src/vlimit.h b/src/vlimit.h new file mode 100644 index 00000000000..c347dc74df6 --- /dev/null +++ b/src/vlimit.h | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | /* Dummy for Emacs so that we can run on VMS... */ | ||
| 2 | #define LIM_DATA 0 | ||
diff --git a/src/vms-pp.c b/src/vms-pp.c index fdfcd9c46a1..2ff47d10daf 100644 --- a/src/vms-pp.c +++ b/src/vms-pp.c | |||
| @@ -16,7 +16,7 @@ GNU General Public License for more details. | |||
| 16 | 16 | ||
| 17 | You should have received a copy of the GNU General Public License | 17 | You should have received a copy of the GNU General Public License |
| 18 | along with GNU Emacs; see the file COPYING. If not, write to | 18 | along with GNU Emacs; see the file COPYING. If not, write to |
| 19 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | 19 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
| 20 | 20 | ||
| 21 | * | 21 | * |
| 22 | * Usage: | 22 | * Usage: |
diff --git a/src/vms-pwd.h b/src/vms-pwd.h new file mode 100644 index 00000000000..6c29197a47a --- /dev/null +++ b/src/vms-pwd.h | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | /* GNU Emacs password definition file. | ||
| 2 | Copyright (C) 1986 Free Software Foundation. | ||
| 3 | |||
| 4 | This file is part of GNU Emacs. | ||
| 5 | |||
| 6 | GNU Emacs is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 1, or (at your option) | ||
| 9 | any later version. | ||
| 10 | |||
| 11 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with GNU Emacs; see the file COPYING. If not, write to | ||
| 18 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
| 19 | |||
| 20 | #ifdef VMS | ||
| 21 | /* On VMS, we read the UAF file and emulate some of the necessary | ||
| 22 | fields for Emacs. */ | ||
| 23 | #include "uaf.h" | ||
| 24 | |||
| 25 | struct passwd { | ||
| 26 | char pw_name[UAF$S_USERNAME+1]; | ||
| 27 | char pw_passwd[UAF$S_PWD]; | ||
| 28 | short pw_uid; | ||
| 29 | short pw_gid; | ||
| 30 | char pw_gecos[UAF$S_OWNER+1]; | ||
| 31 | char pw_dir[UAF$S_DEFDEV+UAF$S_DEFDIR+1]; | ||
| 32 | char pw_shell[UAF$S_DEFCLI+1]; | ||
| 33 | }; | ||
| 34 | #endif /* VMS */ | ||
diff --git a/src/vmsdir.h b/src/vmsdir.h new file mode 100644 index 00000000000..7ea632db625 --- /dev/null +++ b/src/vmsdir.h | |||
| @@ -0,0 +1,97 @@ | |||
| 1 | /* GNU Emacs VMS directory definition file. | ||
| 2 | Copyright (C) 1986 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is part of GNU Emacs. | ||
| 5 | |||
| 6 | GNU Emacs is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 1, or (at your option) | ||
| 9 | any later version. | ||
| 10 | |||
| 11 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with GNU Emacs; see the file COPYING. If not, write to | ||
| 18 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
| 19 | |||
| 20 | /* | ||
| 21 | * Files-11 Ver. 2 directory structure (VMS V4.x - long names) | ||
| 22 | */ | ||
| 23 | #ifndef DIR$K_LENGTH | ||
| 24 | |||
| 25 | #define DIR$C_FID 0 | ||
| 26 | #define DIR$C_LINKNAME 1 | ||
| 27 | #define DIR$K_LENGTH 6 | ||
| 28 | #define DIR$C_LENGTH 6 | ||
| 29 | #define DIR$S_DIRDEF 6 | ||
| 30 | #define DIR$W_SIZE 0 | ||
| 31 | #define DIR$W_VERLIMIT 2 | ||
| 32 | #define DIR$B_FLAGS 4 | ||
| 33 | #define DIR$S_TYPE 3 | ||
| 34 | #define DIR$V_TYPE 0 | ||
| 35 | #define DIR$V_NEXTREC 6 | ||
| 36 | #define DIR$V_PREVREC 7 | ||
| 37 | #define DIR$B_NAMECOUNT 5 | ||
| 38 | #define DIR$S_NAME 80 | ||
| 39 | #define DIR$T_NAME 6 | ||
| 40 | |||
| 41 | #define DIR$K_VERSION 8 | ||
| 42 | #define DIR$C_VERSION 8 | ||
| 43 | #define DIR$S_DIRDEF1 8 | ||
| 44 | #define DIR$W_VERSION 0 | ||
| 45 | #define DIR$S_FID 6 | ||
| 46 | #define DIR$W_FID 2 | ||
| 47 | #define DIR$W_FID_NUM 2 | ||
| 48 | #define DIR$W_FID_SEQ 4 | ||
| 49 | #define DIR$W_FID_RVN 6 | ||
| 50 | #define DIR$B_FID_RVN 6 | ||
| 51 | #define DIR$B_FID_NMX 7 | ||
| 52 | |||
| 53 | #define DIR$S_DIRDEF2 1 | ||
| 54 | #define DIR$T_LINKNAME 0 | ||
| 55 | |||
| 56 | typedef struct dir$_name { | ||
| 57 | /* short dir$w_size; /* if you read with RMS, it eats this... */ | ||
| 58 | short dir$w_verlimit; /* maximum number of versions */ | ||
| 59 | union { | ||
| 60 | unsigned char dir_b_flags; | ||
| 61 | #define dir$b_flags dir__b_flags.dir_b_flags | ||
| 62 | struct { | ||
| 63 | unsigned char dir_v_type: DIR$S_TYPE; | ||
| 64 | #define dir$v_type dir__b_flags.dir___b_flags.dir_v_type | ||
| 65 | unsigned char: 3; | ||
| 66 | unsigned char dir_v_nextrec: 1; | ||
| 67 | #define dir$v_nextrec dir__b_flags.dir___b_flags.dir_v_nextrec | ||
| 68 | unsigned char dir_v_prevrec: 1; | ||
| 69 | #define dir$v_prevrec dir__b_flags.dir___b_flags.dir_v_prevrec | ||
| 70 | } dir___b_flags; | ||
| 71 | } dir__b_flags; | ||
| 72 | unsigned char dir$b_namecount; | ||
| 73 | char dir$t_name[]; | ||
| 74 | } dir$_dirdef; /* only the fixed first part */ | ||
| 75 | |||
| 76 | typedef struct dir$_version { | ||
| 77 | short dir$w_version; | ||
| 78 | short dir$w_fid_num; | ||
| 79 | short dir$w_fid_seq; | ||
| 80 | union { | ||
| 81 | short dir_w_fid_rvn; | ||
| 82 | #define dir$w_fid_rvn dir__w_fid_rvn.dir_w_fid_rvn | ||
| 83 | struct { | ||
| 84 | char dir_b_fid_rvn; | ||
| 85 | #define dir$b_fid_rvn dir__w_fid_rvn.dir___w_fid_rvn.dir_b_fid_rvn | ||
| 86 | char dir_b_fid_nmx; | ||
| 87 | #define dir$b_fid_nmx dir__w_fid_rvn.dir___w_fid_rvn.dir_b_fid_nmx | ||
| 88 | } dir___w_fid_rvn; | ||
| 89 | } dir__w_fid_rvn; | ||
| 90 | } dir$_dirdef1; /* one for each version of the file */ | ||
| 91 | |||
| 92 | typedef | ||
| 93 | struct dir$_linkname { | ||
| 94 | char dir$t_linkname[]; | ||
| 95 | } dir$_dirdef2; | ||
| 96 | |||
| 97 | #endif | ||
diff --git a/src/vmsfns.c b/src/vmsfns.c index 512ab21679a..0885fb694d0 100644 --- a/src/vmsfns.c +++ b/src/vmsfns.c | |||
| @@ -310,7 +310,7 @@ DEFUN ("spawn-subprocess", Fspawn_subprocess, Sspawn_subprocess, 1, 3, 0, | |||
| 310 | prev->next = next; | 310 | prev->next = next; |
| 311 | else | 311 | else |
| 312 | process_list = next; | 312 | process_list = next; |
| 313 | if (! NULL (ptr->exit_handler)) | 313 | if (! NILP (ptr->exit_handler)) |
| 314 | Feval (Fcons (ptr->exit_handler, Fcons (make_number (ptr->name), | 314 | Feval (Fcons (ptr->exit_handler, Fcons (make_number (ptr->name), |
| 315 | Qnil))); | 315 | Qnil))); |
| 316 | sys$dassgn (ptr->mbx_chan); | 316 | sys$dassgn (ptr->mbx_chan); |
| @@ -327,7 +327,7 @@ DEFUN ("spawn-subprocess", Fspawn_subprocess, Sspawn_subprocess, 1, 3, 0, | |||
| 327 | free (ptr); | 327 | free (ptr); |
| 328 | return Qnil; | 328 | return Qnil; |
| 329 | } | 329 | } |
| 330 | if (NULL (input_handler)) | 330 | if (NILP (input_handler)) |
| 331 | input_handler = Qdefault_subproc_input_handler; | 331 | input_handler = Qdefault_subproc_input_handler; |
| 332 | ptr->input_handler = input_handler; | 332 | ptr->input_handler = input_handler; |
| 333 | ptr->exit_handler = exit_handler; | 333 | ptr->exit_handler = exit_handler; |
| @@ -447,7 +447,7 @@ process_command_input () | |||
| 447 | have_process_input = 0; | 447 | have_process_input = 0; |
| 448 | start_mbx_input (); | 448 | start_mbx_input (); |
| 449 | clear_waiting_for_input (); /* Otherwise Ctl-g will cause crash. JCB */ | 449 | clear_waiting_for_input (); /* Otherwise Ctl-g will cause crash. JCB */ |
| 450 | if (! NULL (expr)) | 450 | if (! NILP (expr)) |
| 451 | Feval (expr); | 451 | Feval (expr); |
| 452 | } | 452 | } |
| 453 | 453 | ||
| @@ -471,7 +471,7 @@ process_exit () | |||
| 471 | prev->next = next; | 471 | prev->next = next; |
| 472 | else | 472 | else |
| 473 | process_list = next; | 473 | process_list = next; |
| 474 | if (! NULL (ptr->exit_handler)) | 474 | if (! NILP (ptr->exit_handler)) |
| 475 | Feval (Fcons (ptr->exit_handler, Fcons (make_number (ptr->name), | 475 | Feval (Fcons (ptr->exit_handler, Fcons (make_number (ptr->name), |
| 476 | Qnil))); | 476 | Qnil))); |
| 477 | sys$dassgn (ptr->mbx_chan); | 477 | sys$dassgn (ptr->mbx_chan); |
| @@ -605,9 +605,9 @@ or nil depending upon whether the privilege is already enabled.") | |||
| 605 | } | 605 | } |
| 606 | if (! found) | 606 | if (! found) |
| 607 | error ("Unknown privilege name %s", XSTRING (priv)->data); | 607 | error ("Unknown privilege name %s", XSTRING (priv)->data); |
| 608 | if (NULL (getprv)) | 608 | if (NILP (getprv)) |
| 609 | { | 609 | { |
| 610 | if (sys$setprv (NULL (value) ? 0 : 1, prvmask, 0, 0) == SS$_NORMAL) | 610 | if (sys$setprv (NILP (value) ? 0 : 1, prvmask, 0, 0) == SS$_NORMAL) |
| 611 | return Qt; | 611 | return Qt; |
| 612 | return Qnil; | 612 | return Qnil; |
| 613 | } | 613 | } |
| @@ -679,7 +679,7 @@ translate_id (pid, owner) | |||
| 679 | char * p; | 679 | char * p; |
| 680 | int prcnam[2]; | 680 | int prcnam[2]; |
| 681 | 681 | ||
| 682 | if (NULL (pid) | 682 | if (NILP (pid) |
| 683 | || XTYPE (pid) == Lisp_String && XSTRING (pid)->size == 0 | 683 | || XTYPE (pid) == Lisp_String && XSTRING (pid)->size == 0 |
| 684 | || XTYPE (pid) == Lisp_Int && XFASTINT (pid) == 0) | 684 | || XTYPE (pid) == Lisp_Int && XFASTINT (pid) == 0) |
| 685 | { | 685 | { |
diff --git a/src/vmsmap.c b/src/vmsmap.c new file mode 100644 index 00000000000..aa135302858 --- /dev/null +++ b/src/vmsmap.c | |||
| @@ -0,0 +1,224 @@ | |||
| 1 | /* VMS mapping of data and alloc arena for GNU Emacs. | ||
| 2 | Copyright (C) 1986, 1987 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is part of GNU Emacs. | ||
| 5 | |||
| 6 | GNU Emacs is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 1, or (at your option) | ||
| 9 | any later version. | ||
| 10 | |||
| 11 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with GNU Emacs; see the file COPYING. If not, write to | ||
| 18 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
| 19 | |||
| 20 | /* Written by Mukesh Prasad. */ | ||
| 21 | |||
| 22 | #ifdef VMS | ||
| 23 | |||
| 24 | #include "config.h" | ||
| 25 | #include "lisp.h" | ||
| 26 | #include <rab.h> | ||
| 27 | #include <fab.h> | ||
| 28 | #include <rmsdef.h> | ||
| 29 | #include <secdef.h> | ||
| 30 | |||
| 31 | /* RMS block size */ | ||
| 32 | #define BLOCKSIZE 512 | ||
| 33 | |||
| 34 | /* Maximum number of bytes to be written in one RMS write. | ||
| 35 | * Must be a multiple of BLOCKSIZE. | ||
| 36 | */ | ||
| 37 | #define MAXWRITE (BLOCKSIZE * 30) | ||
| 38 | |||
| 39 | /* This funniness is to ensure that sdata occurs alphabetically BEFORE the | ||
| 40 | $DATA psect and that edata occurs after ALL Emacs psects. This is | ||
| 41 | because the VMS linker sorts all psects in a cluster alphabetically | ||
| 42 | during the linking, unless you use the cluster_psect command. Emacs | ||
| 43 | uses the cluster command to group all Emacs psects into one cluster; | ||
| 44 | this keeps the dumped data separate from any loaded libraries. */ | ||
| 45 | |||
| 46 | globaldef {"$D$ATA"} char sdata[512]; /* Start of saved data area */ | ||
| 47 | globaldef {"__DATA"} char edata[512]; /* End of saved data area */ | ||
| 48 | |||
| 49 | /* Structure to write into first block of map file. | ||
| 50 | */ | ||
| 51 | |||
| 52 | struct map_data | ||
| 53 | { | ||
| 54 | char * sdata; /* Start of data area */ | ||
| 55 | char * edata; /* End of data area */ | ||
| 56 | int datablk; /* Block in file to map data area from/to */ | ||
| 57 | }; | ||
| 58 | |||
| 59 | static void fill_fab (), fill_rab (); | ||
| 60 | static int write_data (); | ||
| 61 | |||
| 62 | extern char *start_of_data (); | ||
| 63 | extern int vms_out_initial; /* Defined in malloc.c */ | ||
| 64 | |||
| 65 | /* Maps in the data and alloc area from the map file. | ||
| 66 | */ | ||
| 67 | |||
| 68 | int | ||
| 69 | mapin_data (name) | ||
| 70 | char * name; | ||
| 71 | { | ||
| 72 | struct FAB fab; | ||
| 73 | struct RAB rab; | ||
| 74 | int status, size; | ||
| 75 | int inadr[2]; | ||
| 76 | struct map_data map_data; | ||
| 77 | |||
| 78 | /* Open map file. */ | ||
| 79 | fab = cc$rms_fab; | ||
| 80 | fab.fab$b_fac = FAB$M_BIO|FAB$M_GET; | ||
| 81 | fab.fab$l_fna = name; | ||
| 82 | fab.fab$b_fns = strlen (name); | ||
| 83 | status = sys$open (&fab); | ||
| 84 | if (status != RMS$_NORMAL) | ||
| 85 | { | ||
| 86 | printf ("Map file not available, running bare Emacs....\n"); | ||
| 87 | return 0; /* Map file not available */ | ||
| 88 | } | ||
| 89 | /* Connect the RAB block */ | ||
| 90 | rab = cc$rms_rab; | ||
| 91 | rab.rab$l_fab = &fab; | ||
| 92 | rab.rab$b_rac = RAB$C_SEQ; | ||
| 93 | rab.rab$l_rop = RAB$M_BIO; | ||
| 94 | status = sys$connect (&rab); | ||
| 95 | if (status != RMS$_NORMAL) | ||
| 96 | lib$stop (status); | ||
| 97 | /* Read the header data */ | ||
| 98 | rab.rab$l_ubf = &map_data; | ||
| 99 | rab.rab$w_usz = sizeof (map_data); | ||
| 100 | rab.rab$l_bkt = 0; | ||
| 101 | status = sys$read (&rab); | ||
| 102 | if (status != RMS$_NORMAL) | ||
| 103 | lib$stop (status); | ||
| 104 | status = sys$close (&fab); | ||
| 105 | if (status != RMS$_NORMAL) | ||
| 106 | lib$stop (status); | ||
| 107 | if (map_data.sdata != start_of_data ()) | ||
| 108 | { | ||
| 109 | printf ("Start of data area has moved: cannot map in data.\n"); | ||
| 110 | return 0; | ||
| 111 | } | ||
| 112 | if (map_data.edata != edata) | ||
| 113 | { | ||
| 114 | printf ("End of data area has moved: cannot map in data.\n"); | ||
| 115 | return 0; | ||
| 116 | } | ||
| 117 | fab.fab$l_fop |= FAB$M_UFO; | ||
| 118 | status = sys$open (&fab); | ||
| 119 | if (status != RMS$_NORMAL) | ||
| 120 | lib$stop (status); | ||
| 121 | /* Map data area. */ | ||
| 122 | inadr[0] = map_data.sdata; | ||
| 123 | inadr[1] = map_data.edata; | ||
| 124 | status = sys$crmpsc (inadr, 0, 0, SEC$M_CRF | SEC$M_WRT, 0, 0, 0, | ||
| 125 | fab.fab$l_stv, 0, map_data.datablk, 0, 0); | ||
| 126 | if (! (status & 1)) | ||
| 127 | lib$stop (status); | ||
| 128 | } | ||
| 129 | |||
| 130 | /* Writes the data and alloc area to the map file. | ||
| 131 | */ | ||
| 132 | mapout_data (into) | ||
| 133 | char * into; | ||
| 134 | { | ||
| 135 | struct FAB fab; | ||
| 136 | struct RAB rab; | ||
| 137 | int status; | ||
| 138 | struct map_data map_data; | ||
| 139 | int datasize, msize; | ||
| 140 | |||
| 141 | if (vms_out_initial) | ||
| 142 | { | ||
| 143 | error ("Out of initial allocation. Must rebuild emacs with more memory (VMS_ALLOCATION_SIZE)."); | ||
| 144 | return 0; | ||
| 145 | } | ||
| 146 | map_data.sdata = start_of_data (); | ||
| 147 | map_data.edata = edata; | ||
| 148 | datasize = map_data.edata - map_data.sdata + 1; | ||
| 149 | map_data.datablk = 2 + (sizeof (map_data) + BLOCKSIZE - 1) / BLOCKSIZE; | ||
| 150 | /* Create map file. */ | ||
| 151 | fab = cc$rms_fab; | ||
| 152 | fab.fab$b_fac = FAB$M_BIO|FAB$M_PUT; | ||
| 153 | fab.fab$l_fna = into; | ||
| 154 | fab.fab$b_fns = strlen (into); | ||
| 155 | fab.fab$l_fop = FAB$M_CBT; | ||
| 156 | fab.fab$b_org = FAB$C_SEQ; | ||
| 157 | fab.fab$b_rat = 0; | ||
| 158 | fab.fab$b_rfm = FAB$C_VAR; | ||
| 159 | fab.fab$l_alq = 1 + map_data.datablk + | ||
| 160 | ((datasize + BLOCKSIZE - 1) / BLOCKSIZE); | ||
| 161 | status = sys$create (&fab); | ||
| 162 | if (status != RMS$_NORMAL) | ||
| 163 | { | ||
| 164 | error ("Could not create map file"); | ||
| 165 | return 0; | ||
| 166 | } | ||
| 167 | /* Connect the RAB block */ | ||
| 168 | rab = cc$rms_rab; | ||
| 169 | rab.rab$l_fab = &fab; | ||
| 170 | rab.rab$b_rac = RAB$C_SEQ; | ||
| 171 | rab.rab$l_rop = RAB$M_BIO; | ||
| 172 | status = sys$connect (&rab); | ||
| 173 | if (status != RMS$_NORMAL) | ||
| 174 | { | ||
| 175 | error ("RMS connect to map file failed"); | ||
| 176 | return 0; | ||
| 177 | } | ||
| 178 | /* Write the header */ | ||
| 179 | rab.rab$l_rbf = &map_data; | ||
| 180 | rab.rab$w_rsz = sizeof (map_data); | ||
| 181 | status = sys$write (&rab); | ||
| 182 | if (status != RMS$_NORMAL) | ||
| 183 | { | ||
| 184 | error ("RMS write (header) to map file failed"); | ||
| 185 | return 0; | ||
| 186 | } | ||
| 187 | if (! write_data (&rab, map_data.datablk, map_data.sdata, datasize)) | ||
| 188 | return 0; | ||
| 189 | status = sys$close (&fab); | ||
| 190 | if (status != RMS$_NORMAL) | ||
| 191 | { | ||
| 192 | error ("RMS close on map file failed"); | ||
| 193 | return 0; | ||
| 194 | } | ||
| 195 | return 1; | ||
| 196 | } | ||
| 197 | |||
| 198 | static int | ||
| 199 | write_data (rab, firstblock, data, length) | ||
| 200 | struct RAB * rab; | ||
| 201 | char * data; | ||
| 202 | { | ||
| 203 | int status; | ||
| 204 | |||
| 205 | rab->rab$l_bkt = firstblock; | ||
| 206 | while (length > 0) | ||
| 207 | { | ||
| 208 | rab->rab$l_rbf = data; | ||
| 209 | rab->rab$w_rsz = length > MAXWRITE ? MAXWRITE : length; | ||
| 210 | status = sys$write (rab, 0, 0); | ||
| 211 | if (status != RMS$_NORMAL) | ||
| 212 | { | ||
| 213 | error ("RMS write to map file failed"); | ||
| 214 | return 0; | ||
| 215 | } | ||
| 216 | data = &data[MAXWRITE]; | ||
| 217 | length -= MAXWRITE; | ||
| 218 | rab->rab$l_bkt = 0; | ||
| 219 | } | ||
| 220 | return 1; | ||
| 221 | } /* write_data */ | ||
| 222 | |||
| 223 | #endif /* VMS */ | ||
| 224 | |||
diff --git a/src/vmspaths.h b/src/vmspaths.h new file mode 100644 index 00000000000..ac16c07b0d0 --- /dev/null +++ b/src/vmspaths.h | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | /* the default search path for Lisp function "load" */ | ||
| 2 | #define PATH_LOADSEARCH "EMACS_LIBRARY:[LISP]" | ||
| 3 | |||
| 4 | /* the extra search path for programs to invoke. | ||
| 5 | This is appended to whatever the PATH environment variable says. */ | ||
| 6 | #define PATH_EXEC "EMACS_LIBRARY:[ETC]" | ||
| 7 | |||
| 8 | /* the name of the directory that contains lock files | ||
| 9 | with which we record what files are being modified in Emacs. | ||
| 10 | This directory should be writable by everyone. */ | ||
| 11 | #define PATH_LOCK "EMACS_LIBRARY:[LOCK]" | ||
| 12 | |||
| 13 | /* the name of the file !!!SuperLock!!! in the directory | ||
| 14 | specified by PATH_LOCK. Yes, this is redundant. */ | ||
| 15 | #define PATH_SUPERLOCK "EMACS_LIBRARY:[LOCK]$$$SUPERLOCK$$$." | ||
diff --git a/src/vmsproc.c b/src/vmsproc.c index ec9678f78a4..fff0aec6d60 100644 --- a/src/vmsproc.c +++ b/src/vmsproc.c | |||
| @@ -437,7 +437,7 @@ if you quit, the process is killed.") | |||
| 437 | 437 | ||
| 438 | CHECK_STRING (args[0], 0); | 438 | CHECK_STRING (args[0], 0); |
| 439 | 439 | ||
| 440 | if (nargs <= 1 || NULL (args[1])) | 440 | if (nargs <= 1 || NILP (args[1])) |
| 441 | args[1] = build_string ("NLA0:"); | 441 | args[1] = build_string ("NLA0:"); |
| 442 | else | 442 | else |
| 443 | args[1] = Fexpand_file_name (args[1], current_buffer->directory); | 443 | args[1] = Fexpand_file_name (args[1], current_buffer->directory); |
| @@ -589,12 +589,12 @@ if you quit, the process is killed.") | |||
| 589 | if (vs->iosb[0] & 1) | 589 | if (vs->iosb[0] & 1) |
| 590 | { | 590 | { |
| 591 | immediate_quit = 0; | 591 | immediate_quit = 0; |
| 592 | if (!NULL (buffer)) | 592 | if (!NILP (buffer)) |
| 593 | { | 593 | { |
| 594 | vs->iosb[1] = clean_vms_buffer (vs->inputBuffer, vs->iosb[1]); | 594 | vs->iosb[1] = clean_vms_buffer (vs->inputBuffer, vs->iosb[1]); |
| 595 | InsCStr (vs->inputBuffer, vs->iosb[1]); | 595 | InsCStr (vs->inputBuffer, vs->iosb[1]); |
| 596 | } | 596 | } |
| 597 | if (!NULL (display) && INTERACTIVE) | 597 | if (!NILP (display) && INTERACTIVE) |
| 598 | redisplay_preserve_echo_area (); | 598 | redisplay_preserve_echo_area (); |
| 599 | immediate_quit = 1; | 599 | immediate_quit = 1; |
| 600 | QUIT; | 600 | QUIT; |
diff --git a/src/vmsproc.h b/src/vmsproc.h new file mode 100644 index 00000000000..f6faddf6a3e --- /dev/null +++ b/src/vmsproc.h | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | /* | ||
| 2 | Structure for storing VMS specific information for an EMACS process | ||
| 3 | |||
| 4 | We use the event flags 1-23 for processes, keyboard input and timer | ||
| 5 | */ | ||
| 6 | |||
| 7 | /* | ||
| 8 | Same as MAXDESC in process.c | ||
| 9 | */ | ||
| 10 | #define MAX_EVENT_FLAGS 23 | ||
| 11 | |||
| 12 | typedef struct { | ||
| 13 | char inputBuffer[1024]; | ||
| 14 | short inputChan; | ||
| 15 | short outputChan; | ||
| 16 | short busy; | ||
| 17 | int pid; | ||
| 18 | int eventFlag; | ||
| 19 | int exitStatus; | ||
| 20 | short iosb[4]; | ||
| 21 | } VMS_PROC_STUFF; | ||
diff --git a/src/xscrollbar.h b/src/xscrollbar.h new file mode 100644 index 00000000000..e1a3f45d247 --- /dev/null +++ b/src/xscrollbar.h | |||
| @@ -0,0 +1,123 @@ | |||
| 1 | /* Bitmaps and things for scrollbars. | ||
| 2 | Copyright (C) 1989 Free Software Foundation. | ||
| 3 | |||
| 4 | This file is part of GNU Emacs. | ||
| 5 | |||
| 6 | GNU Emacs is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 1, or (at your option) | ||
| 9 | any later version. | ||
| 10 | |||
| 11 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with GNU Emacs; see the file COPYING. If not, write to | ||
| 18 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
| 19 | |||
| 20 | |||
| 21 | static void install_vertical_scrollbar (); | ||
| 22 | static void install_horizontal_scrollbar (); | ||
| 23 | static void x_set_horizontal_scrollbar (); | ||
| 24 | static void x_set_vertical_scrollbar (); | ||
| 25 | |||
| 26 | /* Prefix-characters for scroll bar commands in Vglobal_mouse_map. | ||
| 27 | Choice of prefix depends on which region of the scroll bar. */ | ||
| 28 | |||
| 29 | enum scroll_bar_prefix | ||
| 30 | { VSCROLL_BAR_PREFIX = 050, VSCROLL_SLIDER_PREFIX /* unused */, | ||
| 31 | VSCROLL_THUMBUP_PREFIX, VSCROLL_THUMBDOWN_PREFIX, | ||
| 32 | HSCROLL_BAR_PREFIX, HSCROLL_SLIDER_PREFIX /* unused */, | ||
| 33 | HSCROLL_THUMBLEFT_PREFIX, HSCROLL_THUMBRIGHT_PREFIX }; | ||
| 34 | |||
| 35 | #define CROSS_WIDTH 16 | ||
| 36 | #define CROSS_HEIGHT 16 | ||
| 37 | |||
| 38 | #define CROSS_MASK_WIDTH 16 | ||
| 39 | #define CROSS_MASK_HEIGHT 16 | ||
| 40 | |||
| 41 | /* Vertical and Horizontal scroll bar widths. */ | ||
| 42 | #define VSCROLL_WIDTH 18 | ||
| 43 | #define HSCROLL_HEIGHT 18 | ||
| 44 | |||
| 45 | #ifdef HAVE_X11 | ||
| 46 | |||
| 47 | /* Arrow cursors for scroll bars. */ | ||
| 48 | |||
| 49 | Cursor up_arrow_cursor, down_arrow_cursor, v_double_arrow_cursor; | ||
| 50 | Cursor left_arrow_cursor, right_arrow_cursor, h_double_arrow_cursor; | ||
| 51 | |||
| 52 | static char cross_bits[] = | ||
| 53 | { | ||
| 54 | 0x00, 0x00, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, | ||
| 55 | 0x80, 0x01, 0xfe, 0x7f, 0xfe, 0x7f, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, | ||
| 56 | 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x00, 0x00 | ||
| 57 | }; | ||
| 58 | |||
| 59 | static char gray_bits[] = | ||
| 60 | { | ||
| 61 | 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, | ||
| 62 | 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, | ||
| 63 | 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, | ||
| 64 | 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa | ||
| 65 | }; | ||
| 66 | |||
| 67 | static char up_arrow_bits[] = | ||
| 68 | { | ||
| 69 | 0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f, 0xf8, 0x1f, | ||
| 70 | 0xfc, 0x3f, 0xfe, 0x7f, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, | ||
| 71 | 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xff, 0xff | ||
| 72 | }; | ||
| 73 | |||
| 74 | static char down_arrow_bits[] = | ||
| 75 | { | ||
| 76 | 0xff, 0xff, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, | ||
| 77 | 0x80, 0x01, 0x80, 0x01, 0xfe, 0x7f, 0xfc, 0x3f, 0xf8, 0x1f, 0xf0, 0x0f, | ||
| 78 | 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00 | ||
| 79 | }; | ||
| 80 | |||
| 81 | static char left_arrow_bits[] = | ||
| 82 | { | ||
| 83 | 0x00, 0x80, 0x80, 0x80, 0xc0, 0x80, 0xe0, 0x80, 0xf0, 0x80, 0xf8, 0x80, | ||
| 84 | 0xfc, 0x80, 0xfe, 0xff, 0xfe, 0xff, 0xfc, 0x80, 0xf8, 0x80, 0xf0, 0x80, | ||
| 85 | 0xe0, 0x80, 0xc0, 0x80, 0x80, 0x80, 0x00, 0x80 | ||
| 86 | }; | ||
| 87 | |||
| 88 | static char right_arrow_bits[] = | ||
| 89 | { | ||
| 90 | 0x01, 0x00, 0x01, 0x01, 0x01, 0x03, 0x01, 0x07, 0x01, 0x0f, 0x01, 0x1f, | ||
| 91 | 0x01, 0x3f, 0xff, 0x7f, 0xff, 0x7f, 0x01, 0x3f, 0x01, 0x1f, 0x01, 0x0f, | ||
| 92 | 0x01, 0x07, 0x01, 0x03, 0x01, 0x01, 0x01, 0x00 | ||
| 93 | }; | ||
| 94 | |||
| 95 | static char cross_mask_bits[] = | ||
| 96 | { | ||
| 97 | 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, | ||
| 98 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x03, 0xc0, 0x03, | ||
| 99 | 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03 | ||
| 100 | }; | ||
| 101 | #else /* not HAVE_X11 */ | ||
| 102 | static short cross_bits[] = | ||
| 103 | { | ||
| 104 | 0x0000, 0x0180, 0x0180, 0x0180, | ||
| 105 | 0x0180, 0x0180, 0x0180, 0x7ffe, | ||
| 106 | 0x7ffe, 0x0180, 0x0180, 0x0180, | ||
| 107 | 0x0180, 0x0180, 0x0180, 0x0000, | ||
| 108 | }; | ||
| 109 | |||
| 110 | static short gray_bits[] = { | ||
| 111 | 0xaaaa, 0x5555, 0xaaaa, 0x5555, | ||
| 112 | 0xaaaa, 0x5555, 0xaaaa, 0x5555, | ||
| 113 | 0xaaaa, 0x5555, 0xaaaa, 0x5555, | ||
| 114 | 0xaaaa, 0x5555, 0xaaaa, 0x5555}; | ||
| 115 | |||
| 116 | static short cross_mask_bits[] = | ||
| 117 | { | ||
| 118 | 0x03c0, 0x03c0, 0x03c0, 0x03c0, | ||
| 119 | 0x03c0, 0x03c0, 0xffff, 0xffff, | ||
| 120 | 0xffff, 0xffff, 0x03c0, 0x03c0, | ||
| 121 | 0x03c0, 0x03c0, 0x03c0, 0x03c0, | ||
| 122 | }; | ||
| 123 | #endif /* X10 */ | ||