mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-11-24 07:20:37 +00:00
entered into RCS
This commit is contained in:
parent
b2c9579f17
commit
d427b66a66
44
src/XTests.c
44
src/XTests.c
@ -67,8 +67,8 @@ main (argc,argv)
|
||||
int depth;
|
||||
Pixmap pix;
|
||||
char *string = "Kill the head and the body will die.";
|
||||
char dash_list[] = {6, 4, 6, 4};
|
||||
int dashes = 4;
|
||||
char dash_list[] = {4, 4};
|
||||
int dashes = 2;
|
||||
|
||||
if (argc < 2)
|
||||
dpy_string = "localhost:0.0";
|
||||
@ -105,24 +105,19 @@ main (argc,argv)
|
||||
&gc_values);
|
||||
|
||||
gc_values.foreground = obtain_color ("red");
|
||||
gc_values.function = GXor;
|
||||
gc_values.line_width = 3;
|
||||
gc_values.line_style = LineOnOffDash;
|
||||
gc_values.cap_style = CapRound;
|
||||
gc_values.join_style = JoinRound;
|
||||
line_xor_gc = XCreateGC (dpy, window,
|
||||
GCForeground | GCBackground | GCLineStyle
|
||||
| GCJoinStyle | GCCapStyle | GCLineWidth
|
||||
| GCFunction,
|
||||
| GCJoinStyle | GCCapStyle | GCLineWidth,
|
||||
&gc_values);
|
||||
XSetDashes (dpy, line_xor_gc, 0, dash_list, dashes);
|
||||
|
||||
gc_values.background = WhitePixel (dpy, DefaultScreen (dpy));
|
||||
gc_values.foreground = obtain_color ("blue");
|
||||
line_xor_inv_gc = XCreateGC (dpy, window,
|
||||
GCForeground | GCBackground
|
||||
| GCLineWidth | GCFunction,
|
||||
&gc_values);
|
||||
GCForeground | GCBackground | GCLineWidth,
|
||||
&gc_values);
|
||||
|
||||
depth = DefaultDepthOfScreen (ScreenOfDisplay (dpy, DefaultScreen (dpy)));
|
||||
pix = XCreateBitmapFromData (dpy, window, page_glyf_bits,
|
||||
@ -137,25 +132,20 @@ main (argc,argv)
|
||||
switch (event.type)
|
||||
{
|
||||
case ButtonPress:
|
||||
#if 0
|
||||
if (event.xbutton.state && ShiftMask)
|
||||
#endif
|
||||
switch (event.xbutton.button)
|
||||
{
|
||||
case Button1:
|
||||
XDrawLine (dpy, window, line_xor_gc, 25, 75, 125, 75);
|
||||
XFlush (dpy);
|
||||
XDrawLine (dpy, window, line_xor_gc, 25, 75, 125, 75);
|
||||
break;
|
||||
switch (event.xbutton.button)
|
||||
{
|
||||
case Button1:
|
||||
XDrawLine (dpy, window, line_xor_gc, 25, 75, 300, 75);
|
||||
break;
|
||||
|
||||
case Button2:
|
||||
XDrawLine (dpy, window, line_xor_gc, 25, 75, 125, 75);
|
||||
break;
|
||||
case Button2:
|
||||
XDrawLine (dpy, window, line_xor_inv_gc, 25, 25, 300, 25);
|
||||
break;
|
||||
|
||||
case Button3:
|
||||
XDrawLine (dpy, window, line_xor_gc, 25, 75, 125, 75);
|
||||
break;
|
||||
}
|
||||
case Button3:
|
||||
XDrawLine (dpy, window, line_xor_gc, 25, 25, 25, 125);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case KeyPress:
|
||||
|
7
src/XTests.h
Normal file
7
src/XTests.h
Normal file
@ -0,0 +1,7 @@
|
||||
#define page_glyf_width 30
|
||||
#define page_glyf_height 10
|
||||
static char page_glyf_bits[] = {
|
||||
0xf0, 0xff, 0xff, 0x03, 0x08, 0x00, 0x00, 0x04, 0xc4, 0x19, 0xf3, 0x08,
|
||||
0x42, 0xa5, 0x14, 0x10, 0xc1, 0xa5, 0x70, 0x20, 0x41, 0xbc, 0x16, 0x20,
|
||||
0x42, 0xa4, 0x14, 0x10, 0x44, 0x24, 0xf3, 0x08, 0x08, 0x00, 0x00, 0x04,
|
||||
0xf0, 0xff, 0xff, 0x03};
|
45
src/abbrev.c
45
src/abbrev.c
@ -20,7 +20,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#undef NULL
|
||||
#include "lisp.h"
|
||||
#include "commands.h"
|
||||
#include "buffer.h"
|
||||
@ -113,9 +112,9 @@ it is called after EXPANSION is inserted.")
|
||||
Lisp_Object sym, oexp, ohook, tem;
|
||||
CHECK_VECTOR (table, 0);
|
||||
CHECK_STRING (name, 1);
|
||||
if (!NULL (expansion))
|
||||
if (!NILP (expansion))
|
||||
CHECK_STRING (expansion, 2);
|
||||
if (NULL (count))
|
||||
if (NILP (count))
|
||||
count = make_number (0);
|
||||
else
|
||||
CHECK_NUMBER (count, 0);
|
||||
@ -126,10 +125,10 @@ it is called after EXPANSION is inserted.")
|
||||
ohook = XSYMBOL (sym)->function;
|
||||
if (!((EQ (oexp, expansion)
|
||||
|| (XTYPE (oexp) == Lisp_String && XTYPE (expansion) == Lisp_String
|
||||
&& (tem = Fstring_equal (oexp, expansion), !NULL (tem))))
|
||||
&& (tem = Fstring_equal (oexp, expansion), !NILP (tem))))
|
||||
&&
|
||||
(EQ (ohook, hook)
|
||||
|| (tem = Fequal (ohook, hook), !NULL (tem)))))
|
||||
|| (tem = Fequal (ohook, hook), !NILP (tem)))))
|
||||
abbrevs_changed = 1;
|
||||
|
||||
Fset (sym, expansion);
|
||||
@ -156,7 +155,7 @@ DEFUN ("define-mode-abbrev", Fdefine_mode_abbrev, Sdefine_mode_abbrev, 2, 2,
|
||||
(name, expansion)
|
||||
Lisp_Object name, expansion;
|
||||
{
|
||||
if (NULL (current_buffer->abbrev_table))
|
||||
if (NILP (current_buffer->abbrev_table))
|
||||
error ("Major mode has no abbrev table");
|
||||
|
||||
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.")
|
||||
{
|
||||
Lisp_Object sym;
|
||||
CHECK_STRING (abbrev, 0);
|
||||
if (!NULL (table))
|
||||
if (!NILP (table))
|
||||
sym = Fintern_soft (abbrev, table);
|
||||
else
|
||||
{
|
||||
sym = Qnil;
|
||||
if (!NULL (current_buffer->abbrev_table))
|
||||
if (!NILP (current_buffer->abbrev_table))
|
||||
sym = Fintern_soft (abbrev, current_buffer->abbrev_table);
|
||||
if (NULL (XSYMBOL (sym)->value))
|
||||
if (NILP (XSYMBOL (sym)->value))
|
||||
sym = Qnil;
|
||||
if (NULL (sym))
|
||||
if (NILP (sym))
|
||||
sym = Fintern_soft (abbrev, Vglobal_abbrev_table);
|
||||
}
|
||||
if (NULL (XSYMBOL (sym)->value)) return Qnil;
|
||||
if (NILP (XSYMBOL (sym)->value)) return Qnil;
|
||||
return sym;
|
||||
}
|
||||
|
||||
@ -201,7 +200,7 @@ then ABBREV is looked up in that table only.")
|
||||
{
|
||||
Lisp_Object sym;
|
||||
sym = Fabbrev_symbol (abbrev, table);
|
||||
if (NULL (sym)) return sym;
|
||||
if (NILP (sym)) return sym;
|
||||
return Fsymbol_value (sym);
|
||||
}
|
||||
|
||||
@ -221,12 +220,12 @@ Returns t if expansion took place.")
|
||||
register Lisp_Object sym;
|
||||
Lisp_Object expansion, hook, tem;
|
||||
|
||||
if (!NULL (Vrun_hooks))
|
||||
if (!NILP (Vrun_hooks))
|
||||
call1 (Vrun_hooks, Qpre_abbrev_expand_hook);
|
||||
|
||||
if (XBUFFER (Vabbrev_start_location_buffer) != current_buffer)
|
||||
Vabbrev_start_location = Qnil;
|
||||
if (!NULL (Vabbrev_start_location))
|
||||
if (!NILP (Vabbrev_start_location))
|
||||
{
|
||||
tem = Vabbrev_start_location;
|
||||
CHECK_NUMBER_COERCE_MARKER (tem, 0);
|
||||
@ -267,9 +266,9 @@ Returns t if expansion took place.")
|
||||
sym = oblookup (current_buffer->abbrev_table, buffer, p - buffer);
|
||||
else
|
||||
XFASTINT (sym) = 0;
|
||||
if (XTYPE (sym) == Lisp_Int || NULL (XSYMBOL (sym)->value))
|
||||
if (XTYPE (sym) == Lisp_Int || NILP (XSYMBOL (sym)->value))
|
||||
sym = oblookup (Vglobal_abbrev_table, buffer, p - buffer);
|
||||
if (XTYPE (sym) == Lisp_Int || NULL (XSYMBOL (sym)->value))
|
||||
if (XTYPE (sym) == Lisp_Int || NILP (XSYMBOL (sym)->value))
|
||||
return Qnil;
|
||||
|
||||
if (INTERACTIVE && !EQ (minibuf_window, selected_window))
|
||||
@ -327,7 +326,7 @@ Returns t if expansion took place.")
|
||||
}
|
||||
|
||||
hook = XSYMBOL (sym)->function;
|
||||
if (!NULL (hook))
|
||||
if (!NILP (hook))
|
||||
call0 (hook);
|
||||
|
||||
return Qt;
|
||||
@ -367,7 +366,7 @@ write_abbrev (sym, stream)
|
||||
Lisp_Object sym, stream;
|
||||
{
|
||||
Lisp_Object name;
|
||||
if (NULL (XSYMBOL (sym)->value))
|
||||
if (NILP (XSYMBOL (sym)->value))
|
||||
return;
|
||||
insert (" (", 5);
|
||||
XSET (name, Lisp_String, XSYMBOL (sym)->name);
|
||||
@ -387,7 +386,7 @@ describe_abbrev (sym, stream)
|
||||
{
|
||||
Lisp_Object one;
|
||||
|
||||
if (NULL (XSYMBOL (sym)->value))
|
||||
if (NILP (XSYMBOL (sym)->value))
|
||||
return;
|
||||
one = make_number (1);
|
||||
Fprin1 (Fsymbol_name (sym), stream);
|
||||
@ -395,7 +394,7 @@ describe_abbrev (sym, stream)
|
||||
Fprin1 (XSYMBOL (sym)->plist, stream);
|
||||
Findent_to (make_number (20), one);
|
||||
Fprin1 (XSYMBOL (sym)->value, stream);
|
||||
if (!NULL (XSYMBOL (sym)->function))
|
||||
if (!NILP (XSYMBOL (sym)->function))
|
||||
{
|
||||
Findent_to (make_number (45), one);
|
||||
Fprin1 (XSYMBOL (sym)->function, stream);
|
||||
@ -424,7 +423,7 @@ define the abbrev table NAME exactly as it is currently defined.")
|
||||
|
||||
XSET (stream, Lisp_Buffer, current_buffer);
|
||||
|
||||
if (!NULL (readable))
|
||||
if (!NILP (readable))
|
||||
{
|
||||
insert_string ("(");
|
||||
Fprin1 (name, stream);
|
||||
@ -457,7 +456,7 @@ of the form (ABBREVNAME EXPANSION HOOK USECOUNT).")
|
||||
|
||||
CHECK_SYMBOL (tabname, 0);
|
||||
table = Fboundp (tabname);
|
||||
if (NULL (table) || (table = Fsymbol_value (tabname), NULL (table)))
|
||||
if (NILP (table) || (table = Fsymbol_value (tabname), NILP (table)))
|
||||
{
|
||||
table = Fmake_abbrev_table ();
|
||||
Fset (tabname, table);
|
||||
@ -466,7 +465,7 @@ of the form (ABBREVNAME EXPANSION HOOK USECOUNT).")
|
||||
}
|
||||
CHECK_VECTOR (table, 0);
|
||||
|
||||
for (;!NULL (defns); defns = Fcdr (defns))
|
||||
for (;!NILP (defns); defns = Fcdr (defns))
|
||||
{
|
||||
elt = Fcar (defns);
|
||||
name = Fcar (elt);
|
||||
|
40
src/acldef.h
Normal file
40
src/acldef.h
Normal file
@ -0,0 +1,40 @@
|
||||
#define ACL$K_LENGTH 12
|
||||
#define ACL$C_LENGTH 12
|
||||
#define ACL$C_FILE 1
|
||||
#define ACL$C_DEVICE 2
|
||||
#define ACL$C_JOBCTL_QUEUE 3
|
||||
#define ACL$C_COMMON_EF_CLUSTER 4
|
||||
#define ACL$C_LOGICAL_NAME_TABLE 5
|
||||
#define ACL$C_PROCESS 6
|
||||
#define ACL$C_GROUP_GLOBAL_SECTION 7
|
||||
#define ACL$C_SYSTEM_GLOBAL_SECTION 8
|
||||
#define ACL$C_ADDACLENT 1
|
||||
#define ACL$C_DELACLENT 2
|
||||
#define ACL$C_MODACLENT 3
|
||||
#define ACL$C_FNDACLENT 4
|
||||
#define ACL$C_FNDACETYP 5
|
||||
#define ACL$C_DELETEACL 6
|
||||
#define ACL$C_READACL 7
|
||||
#define ACL$C_ACLLENGTH 8
|
||||
#define ACL$C_READACE 9
|
||||
#define ACL$C_RLOCK_ACL 10
|
||||
#define ACL$C_WLOCK_ACL 11
|
||||
#define ACL$C_UNLOCK_ACL 12
|
||||
#define ACL$S_ADDACLENT 255
|
||||
#define ACL$S_DELACLENT 255
|
||||
#define ACL$S_MODACLENT 255
|
||||
#define ACL$S_FNDACLENT 255
|
||||
#define ACL$S_FNDACETYP 255
|
||||
#define ACL$S_DELETEACL 255
|
||||
#define ACL$S_READACL 512
|
||||
#define ACL$S_ACLLENGTH 4
|
||||
#define ACL$S_READACE 255
|
||||
#define ACL$S_RLOCK_ACL 4
|
||||
#define ACL$S_WLOCK_ACL 4
|
||||
#define ACL$S_UNLOCK_ACL 4
|
||||
#define ACL$S_ACLDEF 16
|
||||
#define ACL$L_FLINK 0
|
||||
#define ACL$L_BLINK 4
|
||||
#define ACL$W_SIZE 8
|
||||
#define ACL$B_TYPE 10
|
||||
#define ACL$L_LIST 12
|
@ -261,7 +261,10 @@ syms_of_casefiddle ()
|
||||
keys_of_casefiddle ()
|
||||
{
|
||||
initial_define_key (control_x_map, Ctl('U'), "upcase-region");
|
||||
Fput (intern ("upcase-region"), Qdisabled, Qt);
|
||||
initial_define_key (control_x_map, Ctl('L'), "downcase-region");
|
||||
Fput (intern ("downcase-region"), Qdisabled, Qt);
|
||||
|
||||
initial_define_key (meta_map, 'u', "upcase-word");
|
||||
initial_define_key (meta_map, 'l', "downcase-word");
|
||||
initial_define_key (meta_map, 'c', "capitalize-word");
|
||||
|
@ -45,8 +45,8 @@ See `set-case-table' for more information on these data structures.")
|
||||
(XTYPE (obj) == Lisp_String && XSTRING (obj)->size == 256)
|
||||
|
||||
return (STRING256_P (down)
|
||||
&& (NULL (up) || STRING256_P (up))
|
||||
&& ((NULL (canon) && NULL (eqv))
|
||||
&& (NILP (up) || STRING256_P (up))
|
||||
&& ((NILP (canon) && NILP (eqv))
|
||||
|| (STRING256_P (canon) && STRING256_P (eqv)))
|
||||
? Qt : Qnil);
|
||||
}
|
||||
@ -57,7 +57,7 @@ check_case_table (obj)
|
||||
{
|
||||
register Lisp_Object tem;
|
||||
|
||||
while (tem = Fcase_table_p (obj), NULL (tem))
|
||||
while (tem = Fcase_table_p (obj), NILP (tem))
|
||||
obj = wrong_type_argument (Qcase_table_p, obj, 0);
|
||||
return (obj);
|
||||
}
|
||||
@ -132,13 +132,13 @@ set_case_table (table, standard)
|
||||
canon = Fcar_safe (Fcdr_safe (Fcdr_safe (table)));
|
||||
eqv = Fcar_safe (Fcdr_safe (Fcdr_safe (Fcdr_safe (table))));
|
||||
|
||||
if (NULL (up))
|
||||
if (NILP (up))
|
||||
{
|
||||
up = Fmake_string (make_number (256), make_number (0));
|
||||
compute_trt_inverse (XSTRING (down)->data, XSTRING (up)->data);
|
||||
}
|
||||
|
||||
if (NULL (canon))
|
||||
if (NILP (canon))
|
||||
{
|
||||
register int i;
|
||||
unsigned char *upvec = XSTRING (up)->data;
|
||||
|
38
src/chpdef.h
Normal file
38
src/chpdef.h
Normal file
@ -0,0 +1,38 @@
|
||||
#define CHP$_END 0
|
||||
#define CHP$_ACCESS 1
|
||||
#define CHP$_FLAGS 2
|
||||
#define CHP$_PRIV 3
|
||||
#define CHP$_ACMODE 4
|
||||
#define CHP$_ACCLASS 5
|
||||
#define CHP$_RIGHTS 6
|
||||
#define CHP$_ADDRIGHTS 7
|
||||
#define CHP$_MODE 8
|
||||
#define CHP$_MODES 9
|
||||
#define CHP$_MINCLASS 10
|
||||
#define CHP$_MAXCLASS 11
|
||||
#define CHP$_OWNER 12
|
||||
#define CHP$_PROT 13
|
||||
#define CHP$_ACL 14
|
||||
#define CHP$_AUDITNAME 15
|
||||
#define CHP$_ALARMNAME 16
|
||||
#define CHP$_MATCHEDACE 17
|
||||
#define CHP$_PRIVUSED 18
|
||||
#define CHP$_MAX_CODE 19
|
||||
#define CHP$M_SYSPRV 1
|
||||
#define CHP$M_BYPASS 2
|
||||
#define CHP$M_UPGRADE 4
|
||||
#define CHP$M_DOWNGRADE 8
|
||||
#define CHP$M_GRPPRV 16
|
||||
#define CHP$M_READALL 32
|
||||
#define CHP$V_SYSPRV 0
|
||||
#define CHP$V_BYPASS 1
|
||||
#define CHP$V_UPGRADE 2
|
||||
#define CHP$V_DOWNGRADE 3
|
||||
#define CHP$V_GRPPRV 4
|
||||
#define CHP$V_READALL 5
|
||||
#define CHP$M_READ 1
|
||||
#define CHP$M_WRITE 2
|
||||
#define CHP$M_USEREADALL 4
|
||||
#define CHP$V_READ 0
|
||||
#define CHP$V_WRITE 1
|
||||
#define CHP$V_USEREADALL 2
|
414
src/cm.c
Normal file
414
src/cm.c
Normal file
@ -0,0 +1,414 @@
|
||||
/* Cursor motion subroutines for GNU Emacs.
|
||||
Copyright (C) 1985 Free Software Foundation, Inc.
|
||||
based primarily on public domain code written by Chris Torek
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Emacs is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Emacs; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include "cm.h"
|
||||
#include "termhooks.h"
|
||||
|
||||
#define BIG 9999 /* 9999 good on VAXen. For 16 bit machines
|
||||
use about 2000.... */
|
||||
|
||||
char *tgoto ();
|
||||
|
||||
extern char *BC, *UP;
|
||||
|
||||
int cost; /* sums up costs */
|
||||
|
||||
/* ARGSUSED */
|
||||
evalcost (c)
|
||||
char c;
|
||||
{
|
||||
cost++;
|
||||
}
|
||||
|
||||
void
|
||||
cmputc (c)
|
||||
char c;
|
||||
{
|
||||
if (termscript)
|
||||
fputc (c & 0177, termscript);
|
||||
putchar (c & 0177);
|
||||
}
|
||||
|
||||
/* NEXT TWO ARE DONE WITH MACROS */
|
||||
#if 0
|
||||
/*
|
||||
* Assume the cursor is at row row, column col. Normally used only after
|
||||
* clearing the screen, when the cursor is at (0, 0), but what the heck,
|
||||
* let's let the guy put it anywhere.
|
||||
*/
|
||||
|
||||
static
|
||||
at (row, col) {
|
||||
curY = row;
|
||||
curX = col;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add n columns to the current cursor position.
|
||||
*/
|
||||
|
||||
static
|
||||
addcol (n) {
|
||||
curX += n;
|
||||
|
||||
/*
|
||||
* If cursor hit edge of screen, what happened?
|
||||
* N.B.: DO NOT!! write past edge of screen. If you do, you
|
||||
* deserve what you get. Furthermore, on terminals with
|
||||
* autowrap (but not magicwrap), don't write in the last column
|
||||
* of the last line.
|
||||
*/
|
||||
|
||||
if (curX == Wcm.cm_cols) {
|
||||
/*
|
||||
* Well, if magicwrap, still there, past the edge of the
|
||||
* screen (!). If autowrap, on the col 0 of the next line.
|
||||
* Otherwise on last column.
|
||||
*/
|
||||
|
||||
if (Wcm.cm_magicwrap)
|
||||
; /* "limbo" */
|
||||
else if (Wcm.cm_autowrap) {
|
||||
curX = 0;
|
||||
curY++; /* Beware end of screen! */
|
||||
}
|
||||
else
|
||||
curX--;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* (Re)Initialize the cost factors, given the output speed of the terminal
|
||||
* in the variable ospeed. (Note: this holds B300, B9600, etc -- ie stuff
|
||||
* out of <sgtty.h>.)
|
||||
*/
|
||||
|
||||
cmcostinit ()
|
||||
{
|
||||
char *p;
|
||||
|
||||
#define COST(x,e) (x ? (cost = 0, tputs (x, 1, e), cost) : BIG)
|
||||
#define CMCOST(x,e) ((x == 0) ? BIG : (p = tgoto(x, 0, 0), COST(p ,e)))
|
||||
|
||||
Wcm.cc_up = COST (Wcm.cm_up, evalcost);
|
||||
Wcm.cc_down = COST (Wcm.cm_down, evalcost);
|
||||
Wcm.cc_left = COST (Wcm.cm_left, evalcost);
|
||||
Wcm.cc_right = COST (Wcm.cm_right, evalcost);
|
||||
Wcm.cc_home = COST (Wcm.cm_home, evalcost);
|
||||
Wcm.cc_cr = COST (Wcm.cm_cr, evalcost);
|
||||
Wcm.cc_ll = COST (Wcm.cm_ll, evalcost);
|
||||
Wcm.cc_tab = Wcm.cm_tabwidth ? COST (Wcm.cm_tab, evalcost) : BIG;
|
||||
|
||||
/*
|
||||
* These last three are actually minimum costs. When (if) they are
|
||||
* candidates for the least-cost motion, the real cost is computed.
|
||||
* (Note that "0" is the assumed to generate the minimum cost.
|
||||
* While this is not necessarily true, I have yet to see a terminal
|
||||
* for which is not; all the terminals that have variable-cost
|
||||
* cursor motion seem to take straight numeric values. --ACT)
|
||||
*/
|
||||
|
||||
Wcm.cc_abs = CMCOST (Wcm.cm_abs, evalcost);
|
||||
Wcm.cc_habs = CMCOST (Wcm.cm_habs, evalcost);
|
||||
Wcm.cc_vabs = CMCOST (Wcm.cm_vabs, evalcost);
|
||||
|
||||
#undef CMCOST
|
||||
#undef COST
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the cost to move from (srcy, srcx) to (dsty, dstx) using
|
||||
* up and down, and left and right, motions, and tabs. If doit is set
|
||||
* actually perform the motion.
|
||||
*/
|
||||
|
||||
static
|
||||
calccost (srcy, srcx, dsty, dstx, doit)
|
||||
{
|
||||
register int deltay,
|
||||
deltax,
|
||||
c,
|
||||
totalcost;
|
||||
int ntabs,
|
||||
n2tabs,
|
||||
tabx,
|
||||
tab2x,
|
||||
tabcost;
|
||||
register char *p;
|
||||
|
||||
/* If have just wrapped on a terminal with xn,
|
||||
don't believe the cursor position: give up here
|
||||
and force use of absolute positioning. */
|
||||
|
||||
if (curX == Wcm.cm_cols)
|
||||
goto fail;
|
||||
|
||||
totalcost = 0;
|
||||
if ((deltay = dsty - srcy) == 0)
|
||||
goto x;
|
||||
if (deltay < 0)
|
||||
p = Wcm.cm_up, c = Wcm.cc_up, deltay = -deltay;
|
||||
else
|
||||
p = Wcm.cm_down, c = Wcm.cc_down;
|
||||
if (c == BIG) { /* caint get thar from here */
|
||||
if (doit)
|
||||
printf ("OOPS");
|
||||
return c;
|
||||
}
|
||||
totalcost = c * deltay;
|
||||
if (doit)
|
||||
while (--deltay >= 0)
|
||||
tputs (p, 1, cmputc);
|
||||
x:
|
||||
if ((deltax = dstx - srcx) == 0)
|
||||
goto done;
|
||||
if (deltax < 0) {
|
||||
p = Wcm.cm_left, c = Wcm.cc_left, deltax = -deltax;
|
||||
goto dodelta; /* skip all the tab junk */
|
||||
}
|
||||
/* Tabs (the toughie) */
|
||||
if (Wcm.cc_tab >= BIG || !Wcm.cm_usetabs)
|
||||
goto olddelta; /* forget it! */
|
||||
|
||||
/*
|
||||
* ntabs is # tabs towards but not past dstx; n2tabs is one more
|
||||
* (ie past dstx), but this is only valid if that is not past the
|
||||
* right edge of the screen. We can check that at the same time
|
||||
* as we figure out where we would be if we use the tabs (which
|
||||
* we will put into tabx (for ntabs) and tab2x (for n2tabs)).
|
||||
*/
|
||||
|
||||
ntabs = (deltax + srcx % Wcm.cm_tabwidth) / Wcm.cm_tabwidth;
|
||||
n2tabs = ntabs + 1;
|
||||
tabx = (srcx / Wcm.cm_tabwidth + ntabs) * Wcm.cm_tabwidth;
|
||||
tab2x = tabx + Wcm.cm_tabwidth;
|
||||
|
||||
if (tab2x >= Wcm.cm_cols) /* too far (past edge) */
|
||||
n2tabs = 0;
|
||||
|
||||
/*
|
||||
* Now set tabcost to the cost for using ntabs, and c to the cost
|
||||
* for using n2tabs, then pick the minimum.
|
||||
*/
|
||||
|
||||
/* cost for ntabs + cost for right motion */
|
||||
tabcost = ntabs ? ntabs * Wcm.cc_tab + (dstx - tabx) * Wcm.cc_right
|
||||
: BIG;
|
||||
|
||||
/* cost for n2tabs + cost for left motion */
|
||||
c = n2tabs ? n2tabs * Wcm.cc_tab + (tab2x - dstx) * Wcm.cc_left
|
||||
: BIG;
|
||||
|
||||
if (c < tabcost) /* then cheaper to overshoot & back up */
|
||||
ntabs = n2tabs, tabcost = c, tabx = tab2x;
|
||||
|
||||
if (tabcost >= BIG) /* caint use tabs */
|
||||
goto newdelta;
|
||||
|
||||
/*
|
||||
* See if tabcost is less than just moving right
|
||||
*/
|
||||
|
||||
if (tabcost < (deltax * Wcm.cc_right)) {
|
||||
totalcost += tabcost; /* use the tabs */
|
||||
if (doit)
|
||||
while (--ntabs >= 0)
|
||||
tputs (Wcm.cm_tab, 1, cmputc);
|
||||
srcx = tabx;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now might as well just recompute the delta.
|
||||
*/
|
||||
|
||||
newdelta:
|
||||
if ((deltax = dstx - srcx) == 0)
|
||||
goto done;
|
||||
olddelta:
|
||||
if (deltax > 0)
|
||||
p = Wcm.cm_right, c = Wcm.cc_right;
|
||||
else
|
||||
p = Wcm.cm_left, c = Wcm.cc_left, deltax = -deltax;
|
||||
|
||||
dodelta:
|
||||
if (c == BIG) { /* caint get thar from here */
|
||||
fail:
|
||||
if (doit)
|
||||
printf ("OOPS");
|
||||
return BIG;
|
||||
}
|
||||
totalcost += c * deltax;
|
||||
if (doit)
|
||||
while (--deltax >= 0)
|
||||
tputs (p, 1, cmputc);
|
||||
done:
|
||||
return totalcost;
|
||||
}
|
||||
|
||||
#if 0
|
||||
losecursor ()
|
||||
{
|
||||
curY = -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define USEREL 0
|
||||
#define USEHOME 1
|
||||
#define USELL 2
|
||||
#define USECR 3
|
||||
|
||||
cmgoto (row, col)
|
||||
{
|
||||
int homecost,
|
||||
crcost,
|
||||
llcost,
|
||||
relcost,
|
||||
directcost;
|
||||
int use;
|
||||
char *p,
|
||||
*dcm;
|
||||
|
||||
/* First the degenerate case */
|
||||
if (row == curY && col == curX) /* already there */
|
||||
return;
|
||||
|
||||
if (curY >= 0 && curX >= 0)
|
||||
{
|
||||
/* We may have quick ways to go to the upper-left, bottom-left,
|
||||
* start-of-line, or start-of-next-line. Or it might be best to
|
||||
* start where we are. Examine the options, and pick the cheapest.
|
||||
*/
|
||||
|
||||
relcost = calccost (curY, curX, row, col, 0);
|
||||
use = USEREL;
|
||||
if ((homecost = Wcm.cc_home) < BIG)
|
||||
homecost += calccost (0, 0, row, col, 0);
|
||||
if (homecost < relcost)
|
||||
relcost = homecost, use = USEHOME;
|
||||
if ((llcost = Wcm.cc_ll) < BIG)
|
||||
llcost += calccost (Wcm.cm_rows - 1, 0, row, col, 0);
|
||||
if (llcost < relcost)
|
||||
relcost = llcost, use = USELL;
|
||||
if ((crcost = Wcm.cc_cr) < BIG) {
|
||||
if (Wcm.cm_autolf)
|
||||
if (curY + 1 >= Wcm.cm_rows)
|
||||
crcost = BIG;
|
||||
else
|
||||
crcost += calccost (curY + 1, 0, row, col, 0);
|
||||
else
|
||||
crcost += calccost (curY, 0, row, col, 0);
|
||||
}
|
||||
if (crcost < relcost)
|
||||
relcost = crcost, use = USECR;
|
||||
directcost = Wcm.cc_abs, dcm = Wcm.cm_abs;
|
||||
if (row == curY && Wcm.cc_habs < BIG)
|
||||
directcost = Wcm.cc_habs, dcm = Wcm.cm_habs;
|
||||
else if (col == curX && Wcm.cc_vabs < BIG)
|
||||
directcost = Wcm.cc_vabs, dcm = Wcm.cm_vabs;
|
||||
}
|
||||
else
|
||||
{
|
||||
directcost = 0, relcost = 100000;
|
||||
dcm = Wcm.cm_abs;
|
||||
}
|
||||
|
||||
/*
|
||||
* In the following comparison, the = in <= is because when the costs
|
||||
* are the same, it looks nicer (I think) to move directly there.
|
||||
*/
|
||||
if (directcost <= relcost)
|
||||
{
|
||||
/* compute REAL direct cost */
|
||||
cost = 0;
|
||||
p = dcm == Wcm.cm_habs ? tgoto (dcm, row, col) :
|
||||
tgoto (dcm, col, row);
|
||||
tputs (p, 1, evalcost);
|
||||
if (cost <= relcost)
|
||||
{ /* really is cheaper */
|
||||
tputs (p, 1, cmputc);
|
||||
curY = row, curX = col;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch (use)
|
||||
{
|
||||
case USEHOME:
|
||||
tputs (Wcm.cm_home, 1, cmputc);
|
||||
curY = 0, curX = 0;
|
||||
break;
|
||||
|
||||
case USELL:
|
||||
tputs (Wcm.cm_ll, 1, cmputc);
|
||||
curY = Wcm.cm_rows - 1, curX = 0;
|
||||
break;
|
||||
|
||||
case USECR:
|
||||
tputs (Wcm.cm_cr, 1, cmputc);
|
||||
if (Wcm.cm_autolf)
|
||||
curY++;
|
||||
curX = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
(void) calccost (curY, curX, row, col, 1);
|
||||
curY = row, curX = col;
|
||||
}
|
||||
|
||||
/* Clear out all terminal info.
|
||||
Used before copying into it the info on the actual terminal.
|
||||
*/
|
||||
|
||||
Wcm_clear ()
|
||||
{
|
||||
bzero (&Wcm, sizeof Wcm);
|
||||
UP = 0;
|
||||
BC = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialized stuff
|
||||
* Return 0 if can do CM.
|
||||
* Return -1 if cannot.
|
||||
* Return -2 if size not specified.
|
||||
*/
|
||||
|
||||
Wcm_init ()
|
||||
{
|
||||
#if 0
|
||||
if (Wcm.cm_abs && !Wcm.cm_ds)
|
||||
return 0;
|
||||
#endif
|
||||
if (Wcm.cm_abs)
|
||||
return 0;
|
||||
/* Require up and left, and, if no absolute, down and right */
|
||||
if (!Wcm.cm_up || !Wcm.cm_left)
|
||||
return - 1;
|
||||
if (!Wcm.cm_abs && (!Wcm.cm_down || !Wcm.cm_right))
|
||||
return - 1;
|
||||
/* Check that we know the size of the screen.... */
|
||||
if (Wcm.cm_rows <= 0 || Wcm.cm_cols <= 0)
|
||||
return - 2;
|
||||
return 0;
|
||||
}
|
82
src/disptab.h
Normal file
82
src/disptab.h
Normal file
@ -0,0 +1,82 @@
|
||||
/* Things for GLYPHS and glyph tables.
|
||||
Copyright (C) 1990 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Emacs is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Emacs; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Access the slots of a display-table, according to their purpose. */
|
||||
|
||||
#define DISP_TABLE_SIZE 261
|
||||
#define DISP_TRUNC_GLYPH(dp) ((dp)->contents[256])
|
||||
#define DISP_CONTINUE_GLYPH(dp) ((dp)->contents[257])
|
||||
#define DISP_ESCAPE_GLYPH(dp) ((dp)->contents[258])
|
||||
#define DISP_CTRL_GLYPH(dp) ((dp)->contents[259])
|
||||
#define DISP_INVIS_ROPE(dp) ((dp)->contents[260])
|
||||
#define DISP_CHAR_ROPE(dp, c) ((dp)->contents[c])
|
||||
|
||||
extern struct Lisp_Vector *window_display_table ();
|
||||
|
||||
/* Display table to use for vectors that don't specify their own. */
|
||||
extern Lisp_Object Vstandard_display_table;
|
||||
|
||||
/* Vector of GLYPH definitions. Indexed by GLYPH number,
|
||||
the contents are a string which is how to output the GLYPH. */
|
||||
extern Lisp_Object Vglyph_table;
|
||||
|
||||
/* Return the current length of the GLYPH table,
|
||||
or 0 if the table isn't currently valid. */
|
||||
#define GLYPH_TABLE_LENGTH \
|
||||
((XTYPE (Vglyph_table) == Lisp_Vector) \
|
||||
? XVECTOR (Vglyph_table)->size : 0)
|
||||
|
||||
/* Return the current base (for indexing) of the GLYPH table,
|
||||
or 0 if the table isn't currently valid. */
|
||||
#define GLYPH_TABLE_BASE \
|
||||
((XTYPE (Vglyph_table) == Lisp_Vector) \
|
||||
? XVECTOR (Vglyph_table)->contents : 0)
|
||||
|
||||
/* Given BASE and LEN returned by the two previous macros,
|
||||
return nonzero if the GLYPH code G should be output as a single
|
||||
character with code G. Return zero if G has a string in the table. */
|
||||
#define GLYPH_SIMPLE_P(base,len,g) \
|
||||
((g) >= (len) || XTYPE (base[g]) != Lisp_String)
|
||||
|
||||
/* Given BASE and LEN returned by the two previous macros,
|
||||
return nonzero if GLYPH code G is aliased to a different code. */
|
||||
#define GLYPH_ALIAS_P(base,len,g) \
|
||||
((g) < (len) && XTYPE (base[g]) == Lisp_Int)
|
||||
|
||||
/* Assuming that GLYPH_SIMPLE_P (BASE, LEN, G) is 1,
|
||||
return the alias for G. */
|
||||
#define GLYPH_ALIAS(base, g) XINT (base[g])
|
||||
|
||||
/* Assuming that GLYPH_SIMPLE_P (BASE, LEN, G) is 0,
|
||||
return the length and the address of the character-sequence
|
||||
used for outputting GLYPH G. */
|
||||
#define GLYPH_LENGTH(base,g) XSTRING (base[g])->size
|
||||
#define GLYPH_STRING(base,g) XSTRING (base[g])->data
|
||||
|
||||
/* GLYPH for a space character. */
|
||||
|
||||
#define SPACEGLYPH 040
|
||||
#define NULL_GLYPH 00
|
||||
|
||||
#define GLYPH_FROM_CHAR(c) (c)
|
||||
|
||||
extern int glyphlen ();
|
||||
extern void str_to_glyph_cpy ();
|
||||
extern void str_to_glyph_ncpy ();
|
||||
extern void glyph_to_str_cpy ();
|
@ -68,10 +68,10 @@ doprnt (buffer, bufsize, format, format_end, nargs, args)
|
||||
int size_bound;
|
||||
|
||||
fmt++;
|
||||
/* Copy this one %-spec into fmtcopy. */
|
||||
/* Copy this one %-spec into fmtcpy. */
|
||||
string = fmtcpy;
|
||||
*string++ = '%';
|
||||
while (1)
|
||||
while (string < fmtcpy + sizeof fmtcpy - 1)
|
||||
{
|
||||
*string++ = *fmt;
|
||||
if (! (*fmt >= '0' && *fmt <= '9') && *fmt != '-' && *fmt != ' ')
|
||||
|
34
src/indent.h
Normal file
34
src/indent.h
Normal file
@ -0,0 +1,34 @@
|
||||
/* Definitions for interface to indent.c
|
||||
Copyright (C) 1985, 1986 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Emacs is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Emacs; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
|
||||
struct position
|
||||
{
|
||||
int bufpos;
|
||||
int hpos;
|
||||
int vpos;
|
||||
int prevhpos;
|
||||
int contin;
|
||||
};
|
||||
|
||||
struct position *compute_motion ();
|
||||
struct position *vmotion ();
|
||||
|
||||
/* Value of point when current_column was called */
|
||||
extern int last_known_column_point;
|
20
src/insdel.c
20
src/insdel.c
@ -214,7 +214,7 @@ adjust_markers (from, to, amount)
|
||||
|
||||
marker = current_buffer->markers;
|
||||
|
||||
while (!NULL (marker))
|
||||
while (!NILP (marker))
|
||||
{
|
||||
m = XMARKER (marker);
|
||||
mpos = m->bufpos;
|
||||
@ -352,7 +352,7 @@ insert_from_string (string, pos, length)
|
||||
GPT += length;
|
||||
ZV += length;
|
||||
Z += length;
|
||||
point += length;
|
||||
SET_PT (point + length);
|
||||
|
||||
signal_after_change (point-length, 0, length);
|
||||
}
|
||||
@ -473,22 +473,22 @@ modify_region (start, end)
|
||||
prepare_to_modify_buffer (start, end)
|
||||
Lisp_Object start, end;
|
||||
{
|
||||
if (!NULL (current_buffer->read_only))
|
||||
if (!NILP (current_buffer->read_only))
|
||||
Fbarf_if_buffer_read_only ();
|
||||
|
||||
if (check_protected_fields)
|
||||
Fregion_fields (start, end, Qnil, Qt);
|
||||
|
||||
#ifdef CLASH_DETECTION
|
||||
if (!NULL (current_buffer->filename)
|
||||
if (!NILP (current_buffer->filename)
|
||||
&& current_buffer->save_modified >= MODIFF)
|
||||
lock_file (current_buffer->filename);
|
||||
#else
|
||||
/* At least warn if this file has changed on disk since it was visited. */
|
||||
if (!NULL (current_buffer->filename)
|
||||
if (!NILP (current_buffer->filename)
|
||||
&& current_buffer->save_modified >= MODIFF
|
||||
&& NULL (Fverify_visited_file_modtime (Fcurrent_buffer ()))
|
||||
&& !NULL (Ffile_exists_p (current_buffer->filename)))
|
||||
&& NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
|
||||
&& !NILP (Ffile_exists_p (current_buffer->filename)))
|
||||
call1 (intern ("ask-user-about-supersession-threat"),
|
||||
current_buffer->filename);
|
||||
#endif /* not CLASH_DETECTION */
|
||||
@ -519,12 +519,12 @@ signal_before_change (start, end)
|
||||
{
|
||||
/* If buffer is unmodified, run a special hook for that case. */
|
||||
if (current_buffer->save_modified >= MODIFF
|
||||
&& !NULL (Vfirst_change_function))
|
||||
&& !NILP (Vfirst_change_function))
|
||||
{
|
||||
call0 (Vfirst_change_function);
|
||||
}
|
||||
/* Now in any case run the before-change-function if any. */
|
||||
if (!NULL (Vbefore_change_function))
|
||||
if (!NILP (Vbefore_change_function))
|
||||
{
|
||||
int count = specpdl_ptr - specpdl;
|
||||
Lisp_Object function;
|
||||
@ -551,7 +551,7 @@ signal_before_change (start, end)
|
||||
signal_after_change (pos, lendel, lenins)
|
||||
int pos, lendel, lenins;
|
||||
{
|
||||
if (!NULL (Vafter_change_function))
|
||||
if (!NILP (Vafter_change_function))
|
||||
{
|
||||
int count = specpdl_ptr - specpdl;
|
||||
Lisp_Object function;
|
||||
|
1
src/ioctl.h
Normal file
1
src/ioctl.h
Normal file
@ -0,0 +1 @@
|
||||
/* Emacs ioctl emulation for VMS */
|
38
src/lastfile.c
Normal file
38
src/lastfile.c
Normal file
@ -0,0 +1,38 @@
|
||||
/* Mark end of data space to dump as pure, for GNU Emacs.
|
||||
Copyright (C) 1985 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Emacs is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Emacs; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
|
||||
/* How this works:
|
||||
|
||||
Fdump_emacs dumps everything up to my_edata as text space (pure).
|
||||
|
||||
The files of Emacs are written so as to have no initialized
|
||||
data that can ever need to be altered except at the first startup.
|
||||
This is so that those words can be dumped as sharable text.
|
||||
|
||||
It is not possible to exercise such control over library files.
|
||||
So it is necessary to refrain from making their data areas shared.
|
||||
Therefore, this file is loaded following all the files of Emacs
|
||||
but before library files.
|
||||
As a result, the symbol my_edata indicates the point
|
||||
in data space between data coming from Emacs and data
|
||||
coming from libraries.
|
||||
*/
|
||||
|
||||
char my_edata = 0;
|
7
src/line.h
Normal file
7
src/line.h
Normal file
@ -0,0 +1,7 @@
|
||||
#define line_width 30
|
||||
#define line_height 10
|
||||
static char line_bits[] = {
|
||||
0xf0, 0xff, 0xff, 0x03, 0x08, 0x00, 0x00, 0x04, 0x44, 0x48, 0xf4, 0x08,
|
||||
0x42, 0xc8, 0x14, 0x10, 0x41, 0x48, 0x75, 0x20, 0x41, 0x48, 0x15, 0x20,
|
||||
0x42, 0x48, 0x16, 0x10, 0xc4, 0x4b, 0xf4, 0x08, 0x08, 0x00, 0x00, 0x04,
|
||||
0xf0, 0xff, 0xff, 0x03};
|
31
src/macros.h
Normal file
31
src/macros.h
Normal file
@ -0,0 +1,31 @@
|
||||
/* Definitions for keyboard macro interpretation in GNU Emacs.
|
||||
Copyright (C) 1985 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Emacs is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Emacs; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
|
||||
/* Kbd macro currently being executed (a string) */
|
||||
|
||||
extern Lisp_Object Vexecuting_macro;
|
||||
|
||||
/* Index of next character to fetch from that macro */
|
||||
|
||||
extern int executing_macro_index;
|
||||
|
||||
/* Nonzero while defining a kbd macro */
|
||||
|
||||
extern int defining_kbd_macro;
|
12
src/marker.c
12
src/marker.c
@ -36,7 +36,7 @@ Returns nil if MARKER points into a dead buffer.")
|
||||
{
|
||||
XSET (buf, Lisp_Buffer, XMARKER (marker)->buffer);
|
||||
/* Return marker's buffer only if it is not dead. */
|
||||
if (!NULL (XBUFFER (buf)->name))
|
||||
if (!NILP (XBUFFER (buf)->name))
|
||||
return buf;
|
||||
}
|
||||
return Qnil;
|
||||
@ -87,7 +87,7 @@ Returns MARKER.")
|
||||
CHECK_MARKER (marker, 0);
|
||||
/* If position is nil or a marker that points nowhere,
|
||||
make this marker point nowhere. */
|
||||
if (NULL (pos)
|
||||
if (NILP (pos)
|
||||
|| (XTYPE (pos) == Lisp_Marker && !XMARKER (pos)->buffer))
|
||||
{
|
||||
unchain_marker (marker);
|
||||
@ -95,7 +95,7 @@ Returns MARKER.")
|
||||
}
|
||||
|
||||
CHECK_NUMBER_COERCE_MARKER (pos, 1);
|
||||
if (NULL (buffer))
|
||||
if (NILP (buffer))
|
||||
b = current_buffer;
|
||||
else
|
||||
{
|
||||
@ -144,7 +144,7 @@ set_marker_restricted (marker, pos, buffer)
|
||||
CHECK_MARKER (marker, 0);
|
||||
/* If position is nil or a marker that points nowhere,
|
||||
make this marker point nowhere. */
|
||||
if (NULL (pos) ||
|
||||
if (NILP (pos) ||
|
||||
(XTYPE (pos) == Lisp_Marker && !XMARKER (pos)->buffer))
|
||||
{
|
||||
unchain_marker (marker);
|
||||
@ -152,7 +152,7 @@ set_marker_restricted (marker, pos, buffer)
|
||||
}
|
||||
|
||||
CHECK_NUMBER_COERCE_MARKER (pos, 1);
|
||||
if (NULL (buffer))
|
||||
if (NILP (buffer))
|
||||
b = current_buffer;
|
||||
else
|
||||
{
|
||||
@ -215,7 +215,7 @@ unchain_marker (marker)
|
||||
|
||||
if (XMARKER (marker) == XMARKER (tail))
|
||||
{
|
||||
if (NULL (prev))
|
||||
if (NILP (prev))
|
||||
{
|
||||
b->markers = next;
|
||||
/* Deleting first marker from the buffer's chain.
|
||||
|
@ -32,7 +32,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
* {
|
||||
* Lisp_Object elt;
|
||||
*
|
||||
* while (!NULL (args))
|
||||
* while (!NILP (args))
|
||||
* {
|
||||
* elt = Fcar (args);
|
||||
* 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'.")
|
||||
struct gcpro gcpro1;
|
||||
|
||||
GCPRO1 (args);
|
||||
while (!NULL (args))
|
||||
while (!NILP (args))
|
||||
{
|
||||
val = Feval (Fcar (args));
|
||||
args = Fcdr (args);
|
||||
if (NULL (args)) break;
|
||||
if (NILP (args)) break;
|
||||
if (XINT (val))
|
||||
{
|
||||
val = Feval (Fcar (args));
|
||||
@ -156,7 +156,7 @@ DEFUN ("ml-prefix-argument-loop", Fml_prefix_argument_loop, Sml_prefix_argument_
|
||||
struct gcpro gcpro1;
|
||||
|
||||
/* Set `arg' in case we call a built-in function that looks at it. Still are a few. */
|
||||
if (NULL (Vcurrent_prefix_arg))
|
||||
if (NILP (Vcurrent_prefix_arg))
|
||||
i = 1;
|
||||
else
|
||||
{
|
||||
|
@ -28,4 +28,4 @@ extern Lisp_Object Fml_arg ();
|
||||
extern Lisp_Object Fml_interactive ();
|
||||
extern Lisp_Object Fml_provide_prefix_argument ();
|
||||
extern Lisp_Object Fml_prefix_argument_loop ();
|
||||
extern Lisp_Object FInsStr ();
|
||||
extern Lisp_Object Finsert_string ();
|
||||
|
51
src/ndir.h
Normal file
51
src/ndir.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
<dir.h> -- definitions for 4.2BSD-compatible directory access
|
||||
|
||||
last edit: 09-Jul-1983 D A Gwyn
|
||||
*/
|
||||
|
||||
#ifdef VMS
|
||||
#ifndef FAB$C_BID
|
||||
#include <fab.h>
|
||||
#endif
|
||||
#ifndef NAM$C_BID
|
||||
#include <nam.h>
|
||||
#endif
|
||||
#ifndef RMS$_SUC
|
||||
#include <rmsdef.h>
|
||||
#endif
|
||||
#include "dir.h"
|
||||
#endif /* VMS */
|
||||
|
||||
#define DIRBLKSIZ 512 /* size of directory block */
|
||||
#ifdef VMS
|
||||
#define MAXNAMLEN (DIR$S_NAME + 7) /* 80 plus room for version #. */
|
||||
#define MAXFULLSPEC NAM$C_MAXRSS /* Maximum full spec */
|
||||
#else
|
||||
#define MAXNAMLEN 15 /* maximum filename length */
|
||||
#endif /* VMS */
|
||||
/* NOTE: MAXNAMLEN must be one less than a multiple of 4 */
|
||||
|
||||
struct direct /* data from readdir() */
|
||||
{
|
||||
long d_ino; /* inode number of entry */
|
||||
unsigned short d_reclen; /* length of this record */
|
||||
unsigned short d_namlen; /* length of string in d_name */
|
||||
char d_name[MAXNAMLEN+1]; /* name of file */
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int dd_fd; /* file descriptor */
|
||||
int dd_loc; /* offset in block */
|
||||
int dd_size; /* amount of valid data */
|
||||
char dd_buf[DIRBLKSIZ]; /* directory block */
|
||||
} DIR; /* stream data from opendir() */
|
||||
|
||||
extern DIR *opendir();
|
||||
extern struct direct *readdir();
|
||||
extern long telldir();
|
||||
extern void seekdir();
|
||||
extern void closedir();
|
||||
|
||||
#define rewinddir( dirp ) seekdir( dirp, 0L )
|
2
src/param.h
Normal file
2
src/param.h
Normal file
@ -0,0 +1,2 @@
|
||||
/* This is so that Emacs can run on VMS... */
|
||||
#define EXEC_PAGESIZE 512
|
5
src/point.h
Normal file
5
src/point.h
Normal file
@ -0,0 +1,5 @@
|
||||
#define point_width 5
|
||||
#define point_height 19
|
||||
static char point_bits[] = {
|
||||
0x1f, 0x0e, 0x0e, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x04, 0x04, 0x0e, 0x0e, 0x1f};
|
9
src/pre-crt0.c
Normal file
9
src/pre-crt0.c
Normal file
@ -0,0 +1,9 @@
|
||||
/* This file is loaded before crt0.o on machines where we do not
|
||||
remap part of the data space into text space in unexec.
|
||||
On these machines, there is no problem with standard crt0.o's
|
||||
that make environ an initialized variable. However, we do
|
||||
need to make sure the label data_start exists anyway. */
|
||||
|
||||
/* Create a label to appear at the beginning of data space. */
|
||||
|
||||
int data_start = 0;
|
@ -21,9 +21,19 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
At one point, this was defined in config.h, meaning that changing
|
||||
PURESIZE would make Make recompile all of Emacs. But only a few
|
||||
files actually use PURESIZE, so we split it out to its own .h file. */
|
||||
files actually use PURESIZE, so we split it out to its own .h file.
|
||||
|
||||
Make sure to include this file after config.h, since that tells us
|
||||
whether we are running X windows, which tells us how much pure
|
||||
storage to allocate. */
|
||||
|
||||
#ifndef PURESIZE
|
||||
#ifdef HAVE_X_WINDOWS
|
||||
#define PURESIZE 200000
|
||||
#else
|
||||
#define PURESIZE 196000
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef VIRT_ADDR_VARIES
|
||||
|
||||
|
91
src/sink.h
Normal file
91
src/sink.h
Normal file
@ -0,0 +1,91 @@
|
||||
#define sink_width 48
|
||||
#define sink_height 48
|
||||
#ifdef HAVE_X11
|
||||
static char sink_bits[] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0x80, 0x9f,
|
||||
0xff, 0xff, 0xff, 0xff, 0x9f, 0x9f,
|
||||
0xff, 0xff, 0xff, 0xff, 0x00, 0x80,
|
||||
0xff, 0xff, 0xff, 0x7f, 0xfe, 0xbf,
|
||||
0xff, 0xff, 0xff, 0x7f, 0x03, 0xa0,
|
||||
0xff, 0xff, 0xff, 0x7f, 0xfd, 0xaf,
|
||||
0xff, 0xff, 0xff, 0x3f, 0xf9, 0xaf,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xaf,
|
||||
0xff, 0xff, 0xff, 0xff, 0xfc, 0xaf,
|
||||
0xff, 0xff, 0xff, 0x7f, 0xf8, 0xaf,
|
||||
0xff, 0xff, 0xff, 0xff, 0xfc, 0xaf,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xaf,
|
||||
0xff, 0xff, 0xff, 0xbf, 0xf7, 0xaf,
|
||||
0xff, 0xff, 0xff, 0x3f, 0xf3, 0xaf,
|
||||
0xff, 0xff, 0xff, 0xff, 0xfc, 0xaf,
|
||||
0x3f, 0x00, 0x00, 0x00, 0x00, 0x20,
|
||||
0x7f, 0x00, 0x00, 0x00, 0x00, 0xe0,
|
||||
0xdf, 0xf8, 0xff, 0xff, 0xff, 0x07,
|
||||
0xcf, 0xf9, 0x0f, 0xff, 0xff, 0xe7,
|
||||
0xcf, 0xf9, 0xf7, 0xff, 0xff, 0xe7,
|
||||
0xff, 0xf9, 0xf7, 0x63, 0xfb, 0xe7,
|
||||
0xff, 0xf9, 0x37, 0x5a, 0xfb, 0xe7,
|
||||
0xcf, 0xf9, 0xf7, 0x5a, 0xfb, 0xe7,
|
||||
0xcf, 0xf9, 0xf7, 0x5a, 0xf9, 0xe7,
|
||||
0xef, 0xf9, 0x0f, 0xdb, 0xfa, 0xe7,
|
||||
0xff, 0xf9, 0xff, 0xff, 0xff, 0xe7,
|
||||
0xdf, 0xf9, 0xff, 0xff, 0xff, 0xe7,
|
||||
0xcf, 0x19, 0xfc, 0xff, 0xff, 0xe7,
|
||||
0xcf, 0xd9, 0xff, 0xff, 0xff, 0xe7,
|
||||
0xff, 0xd9, 0x47, 0xce, 0x73, 0xe6,
|
||||
0xff, 0x19, 0xb6, 0xb5, 0xad, 0xe7,
|
||||
0xcf, 0xd9, 0xb7, 0xb5, 0x7d, 0xe6,
|
||||
0xc7, 0xd9, 0xb7, 0xb5, 0xed, 0xe5,
|
||||
0xef, 0x19, 0xb4, 0x4d, 0x73, 0xe6,
|
||||
0xff, 0xf1, 0xff, 0xff, 0xff, 0xe3,
|
||||
0xff, 0x03, 0x80, 0x03, 0x00, 0xf0,
|
||||
0xef, 0x07, 0x00, 0x01, 0x00, 0xf8,
|
||||
0xc7, 0xff, 0x3f, 0xf9, 0xff, 0xff,
|
||||
0xe7, 0xff, 0x7f, 0xfd, 0xe0, 0xff,
|
||||
0xff, 0xff, 0x7f, 0x7d, 0xdf, 0xff,
|
||||
0xff, 0xff, 0x7f, 0xbd, 0xb1, 0xff,
|
||||
0xff, 0xff, 0x7f, 0xbb, 0xae, 0xff,
|
||||
0xef, 0xff, 0xff, 0xda, 0xae, 0xff,
|
||||
0xc7, 0xff, 0xff, 0x66, 0xaf, 0xff,
|
||||
0xe7, 0xff, 0xff, 0xbd, 0xaf, 0xff,
|
||||
0xff, 0xff, 0xff, 0xc3, 0xaf, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xaf, 0xff};
|
||||
#else
|
||||
short sink_bits[] = {
|
||||
0xffff, 0xffff, 0xffff, 0xffff,
|
||||
0xffff, 0x9f80, 0xffff, 0xffff,
|
||||
0x9f9f, 0xffff, 0xffff, 0x8000,
|
||||
0xffff, 0x7fff, 0xbffe, 0xffff,
|
||||
0x7fff, 0xa003, 0xffff, 0x7fff,
|
||||
0xaffd, 0xffff, 0x3fff, 0xaff9,
|
||||
0xffff, 0xffff, 0xafff, 0xffff,
|
||||
0xffff, 0xaffc, 0xffff, 0x7fff,
|
||||
0xaff8, 0xffff, 0xffff, 0xaffc,
|
||||
0xffff, 0xffff, 0xafff, 0xffff,
|
||||
0xbfff, 0xaff7, 0xffff, 0x3fff,
|
||||
0xaff3, 0xffff, 0xffff, 0xaffc,
|
||||
0x003f, 0x0000, 0x2000, 0x007f,
|
||||
0x0000, 0xe000, 0xf8df, 0xffff,
|
||||
0x07ff, 0xf9cf, 0xff0f, 0xe7ff,
|
||||
0xf9cf, 0xfff7, 0xe7ff, 0xf9ff,
|
||||
0x63f7, 0xe7fb, 0xf9ff, 0x5a37,
|
||||
0xe7fb, 0xf9cf, 0x5af7, 0xe7fb,
|
||||
0xf9cf, 0x5af7, 0xe7f9, 0xf9ef,
|
||||
0xdb0f, 0xe7fa, 0xf9ff, 0xffff,
|
||||
0xe7ff, 0xf9df, 0xffff, 0xe7ff,
|
||||
0x19cf, 0xfffc, 0xe7ff, 0xd9cf,
|
||||
0xffff, 0xe7ff, 0xd9ff, 0xce47,
|
||||
0xe673, 0x19ff, 0xb5b6, 0xe7ad,
|
||||
0xd9cf, 0xb5b7, 0xe67d, 0xd9c7,
|
||||
0xb5b7, 0xe5ed, 0x19ef, 0x4db4,
|
||||
0xe673, 0xf1ff, 0xffff, 0xe3ff,
|
||||
0x03ff, 0x0380, 0xf000, 0x07ef,
|
||||
0x0100, 0xf800, 0xffc7, 0xf93f,
|
||||
0xffff, 0xffe7, 0xfd7f, 0xffe0,
|
||||
0xffff, 0x7d7f, 0xffdf, 0xffff,
|
||||
0xbd7f, 0xffb1, 0xffff, 0xbb7f,
|
||||
0xffae, 0xffef, 0xdaff, 0xffae,
|
||||
0xffc7, 0x66ff, 0xffaf, 0xffe7,
|
||||
0xbdff, 0xffaf, 0xffff, 0xc3ff,
|
||||
0xffaf, 0xffff, 0xffff, 0xffaf};
|
||||
#endif /* HAVE_X11 */
|
51
src/sink11.h
Normal file
51
src/sink11.h
Normal file
@ -0,0 +1,51 @@
|
||||
#define sink_width 48
|
||||
#define sink_height 48
|
||||
static char sink_bits[] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0x80, 0x9f,
|
||||
0xff, 0xff, 0xff, 0xff, 0x9f, 0x9f,
|
||||
0xff, 0xff, 0xff, 0xff, 0x00, 0x80,
|
||||
0xff, 0xff, 0xff, 0x7f, 0xfe, 0xbf,
|
||||
0xff, 0xff, 0xff, 0x7f, 0x03, 0xa0,
|
||||
0xff, 0xff, 0xff, 0x7f, 0xfd, 0xaf,
|
||||
0xff, 0xff, 0xff, 0x3f, 0xf9, 0xaf,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xaf,
|
||||
0xff, 0xff, 0xff, 0xff, 0xfc, 0xaf,
|
||||
0xff, 0xff, 0xff, 0x7f, 0xf8, 0xaf,
|
||||
0xff, 0xff, 0xff, 0xff, 0xfc, 0xaf,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xaf,
|
||||
0xff, 0xff, 0xff, 0xbf, 0xf7, 0xaf,
|
||||
0xff, 0xff, 0xff, 0x3f, 0xf3, 0xaf,
|
||||
0xff, 0xff, 0xff, 0xff, 0xfc, 0xaf,
|
||||
0x3f, 0x00, 0x00, 0x00, 0x00, 0x20,
|
||||
0x7f, 0x00, 0x00, 0x00, 0x00, 0xe0,
|
||||
0xdf, 0xf8, 0xff, 0xff, 0xff, 0x07,
|
||||
0xcf, 0xf9, 0x0f, 0xff, 0xff, 0xe7,
|
||||
0xcf, 0xf9, 0xf7, 0xff, 0xff, 0xe7,
|
||||
0xff, 0xf9, 0xf7, 0x63, 0xfb, 0xe7,
|
||||
0xff, 0xf9, 0x37, 0x5a, 0xfb, 0xe7,
|
||||
0xcf, 0xf9, 0xf7, 0x5a, 0xfb, 0xe7,
|
||||
0xcf, 0xf9, 0xf7, 0x5a, 0xf9, 0xe7,
|
||||
0xef, 0xf9, 0x0f, 0xdb, 0xfa, 0xe7,
|
||||
0xff, 0xf9, 0xff, 0xff, 0xff, 0xe7,
|
||||
0xdf, 0xf9, 0xff, 0xff, 0xff, 0xe7,
|
||||
0xcf, 0x19, 0xfc, 0xff, 0xff, 0xe7,
|
||||
0xcf, 0xd9, 0xff, 0xff, 0xff, 0xe7,
|
||||
0xff, 0xd9, 0x47, 0xce, 0x73, 0xe6,
|
||||
0xff, 0x19, 0xb6, 0xb5, 0xad, 0xe7,
|
||||
0xcf, 0xd9, 0xb7, 0xb5, 0x7d, 0xe6,
|
||||
0xc7, 0xd9, 0xb7, 0xb5, 0xed, 0xe5,
|
||||
0xef, 0x19, 0xb4, 0x4d, 0x73, 0xe6,
|
||||
0xff, 0xf1, 0xff, 0xff, 0xff, 0xe3,
|
||||
0xff, 0x03, 0x80, 0x03, 0x00, 0xf0,
|
||||
0xef, 0x07, 0x00, 0x01, 0x00, 0xf8,
|
||||
0xc7, 0xff, 0x3f, 0xf9, 0xff, 0xff,
|
||||
0xe7, 0xff, 0x7f, 0xfd, 0xe0, 0xff,
|
||||
0xff, 0xff, 0x7f, 0x7d, 0xdf, 0xff,
|
||||
0xff, 0xff, 0x7f, 0xbd, 0xb1, 0xff,
|
||||
0xff, 0xff, 0x7f, 0xbb, 0xae, 0xff,
|
||||
0xef, 0xff, 0xff, 0xda, 0xae, 0xff,
|
||||
0xc7, 0xff, 0xff, 0x66, 0xaf, 0xff,
|
||||
0xe7, 0xff, 0xff, 0xbd, 0xaf, 0xff,
|
||||
0xff, 0xff, 0xff, 0xc3, 0xaf, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xaf, 0xff};
|
51
src/sink11mask.h
Normal file
51
src/sink11mask.h
Normal file
@ -0,0 +1,51 @@
|
||||
#define sink_mask_width 48
|
||||
#define sink_mask_height 48
|
||||
static char sink_mask_bits[] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
50
src/terminfo.c
Normal file
50
src/terminfo.c
Normal file
@ -0,0 +1,50 @@
|
||||
/* Interface from Emacs to terminfo.
|
||||
Copyright (C) 1985, 1986 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Emacs is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Emacs; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Define these variables that serve as global parameters to termcap,
|
||||
so that we do not need to conditionalize the places in Emacs
|
||||
that set them. */
|
||||
|
||||
char *UP, *BC, PC;
|
||||
short ospeed;
|
||||
|
||||
static buffer[512];
|
||||
|
||||
/* Interface to curses/terminfo library.
|
||||
Turns out that all of the terminfo-level routines look
|
||||
like their termcap counterparts except for tparm, which replaces
|
||||
tgoto. Not only is the calling sequence different, but the string
|
||||
format is different too.
|
||||
*/
|
||||
|
||||
char *
|
||||
tparam (string, outstring, len, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
|
||||
char *string;
|
||||
char *outstring;
|
||||
int arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9;
|
||||
{
|
||||
char *temp;
|
||||
extern char *tparm();
|
||||
|
||||
temp = tparm (string, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
|
||||
if (outstring == 0)
|
||||
outstring = ((char *) (malloc ((strlen (temp)) + 1)));
|
||||
strcpy (outstring, temp);
|
||||
return outstring;
|
||||
}
|
25
src/uaf.h
25
src/uaf.h
@ -3,20 +3,19 @@
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY. No author or distributor
|
||||
accepts responsibility to anyone for the consequences of using it
|
||||
or for whether it serves any particular purpose or works at all,
|
||||
unless he says so in writing. Refer to the GNU Emacs General Public
|
||||
License for full details.
|
||||
GNU Emacs is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
Everyone is granted permission to copy, modify and redistribute
|
||||
GNU Emacs, but only under the conditions described in the
|
||||
GNU Emacs General Public License. A copy of this license is
|
||||
supposed to have been given to you along with GNU Emacs so you
|
||||
can know your rights and responsibilities. It should be in a
|
||||
file named COPYING. Among other things, the copyright notice
|
||||
and this notice must be preserved on all copies. */
|
||||
GNU Emacs is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Emacs; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/*
|
||||
* User Authorization File record formats
|
||||
|
601
src/unexconvex.c
Normal file
601
src/unexconvex.c
Normal file
@ -0,0 +1,601 @@
|
||||
/* Modified version of unexec for convex machines.
|
||||
Note that the GNU project considers support for the peculiarities
|
||||
of the Convex operating system a peripheral activity which should
|
||||
not be allowed to divert effort from development of the GNU system.
|
||||
Changes in this code will be installed when Convex system
|
||||
maintainers send them in, but aside from that we don't plan to
|
||||
think about it, or about whether other Emacs maintenance might
|
||||
break it.
|
||||
|
||||
Copyright (C) 1985, 1986, 1988 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Emacs is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Emacs; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
|
||||
/* modified for C-1 arch by jthomp@convex 871103 */
|
||||
/* Corrected to support convex SOFF object file formats and thread specific
|
||||
* regions. streepy@convex 890302
|
||||
*/
|
||||
|
||||
/*
|
||||
* unexec.c - Convert a running program into an a.out file.
|
||||
*
|
||||
* Author: Spencer W. Thomas
|
||||
* Computer Science Dept.
|
||||
* University of Utah
|
||||
* Date: Tue Mar 2 1982
|
||||
* Modified heavily since then.
|
||||
*
|
||||
* Synopsis:
|
||||
* unexec (new_name, a_name, data_start, bss_start, entry_address)
|
||||
* char *new_name, *a_name;
|
||||
* unsigned data_start, bss_start, entry_address;
|
||||
*
|
||||
* Takes a snapshot of the program and makes an a.out format file in the
|
||||
* file named by the string argument new_name.
|
||||
* If a_name is non-NULL, the symbol table will be taken from the given file.
|
||||
* On some machines, an existing a_name file is required.
|
||||
*
|
||||
* The boundaries within the a.out file may be adjusted with the data_start
|
||||
* and bss_start arguments. Either or both may be given as 0 for defaults.
|
||||
*
|
||||
* Data_start gives the boundary between the text segment and the data
|
||||
* segment of the program. The text segment can contain shared, read-only
|
||||
* program code and literal data, while the data segment is always unshared
|
||||
* and unprotected. Data_start gives the lowest unprotected address.
|
||||
* The value you specify may be rounded down to a suitable boundary
|
||||
* as required by the machine you are using.
|
||||
*
|
||||
* Specifying zero for data_start means the boundary between text and data
|
||||
* should not be the same as when the program was loaded.
|
||||
* If NO_REMAP is defined, the argument data_start is ignored and the
|
||||
* segment boundaries are never changed.
|
||||
*
|
||||
* Bss_start indicates how much of the data segment is to be saved in the
|
||||
* a.out file and restored when the program is executed. It gives the lowest
|
||||
* unsaved address, and is rounded up to a page boundary. The default when 0
|
||||
* is given assumes that the entire data segment is to be stored, including
|
||||
* the previous data and bss as well as any additional storage allocated with
|
||||
* break (2).
|
||||
*
|
||||
* The new file is set up to start at entry_address.
|
||||
*
|
||||
* If you make improvements I'd like to get them too.
|
||||
* harpo!utah-cs!thomas, thomas@Utah-20
|
||||
*
|
||||
*/
|
||||
|
||||
/* There are several compilation parameters affecting unexec:
|
||||
|
||||
* COFF
|
||||
|
||||
Define this if your system uses COFF for executables.
|
||||
Otherwise we assume you use Berkeley format.
|
||||
|
||||
* NO_REMAP
|
||||
|
||||
Define this if you do not want to try to save Emacs's pure data areas
|
||||
as part of the text segment.
|
||||
|
||||
Saving them as text is good because it allows users to share more.
|
||||
|
||||
However, on machines that locate the text area far from the data area,
|
||||
the boundary cannot feasibly be moved. Such machines require
|
||||
NO_REMAP.
|
||||
|
||||
Also, remapping can cause trouble with the built-in startup routine
|
||||
/lib/crt0.o, which defines `environ' as an initialized variable.
|
||||
Dumping `environ' as pure does not work! So, to use remapping,
|
||||
you must write a startup routine for your machine in Emacs's crt0.c.
|
||||
If NO_REMAP is defined, Emacs uses the system's crt0.o.
|
||||
|
||||
* SECTION_ALIGNMENT
|
||||
|
||||
Some machines that use COFF executables require that each section
|
||||
start on a certain boundary *in the COFF file*. Such machines should
|
||||
define SECTION_ALIGNMENT to a mask of the low-order bits that must be
|
||||
zero on such a boundary. This mask is used to control padding between
|
||||
segments in the COFF file.
|
||||
|
||||
If SECTION_ALIGNMENT is not defined, the segments are written
|
||||
consecutively with no attempt at alignment. This is right for
|
||||
unmodified system V.
|
||||
|
||||
* SEGMENT_MASK
|
||||
|
||||
Some machines require that the beginnings and ends of segments
|
||||
*in core* be on certain boundaries. For most machines, a page
|
||||
boundary is sufficient. That is the default. When a larger
|
||||
boundary is needed, define SEGMENT_MASK to a mask of
|
||||
the bits that must be zero on such a boundary.
|
||||
|
||||
* A_TEXT_OFFSET(HDR)
|
||||
|
||||
Some machines count the a.out header as part of the size of the text
|
||||
segment (a_text); they may actually load the header into core as the
|
||||
first data in the text segment. Some have additional padding between
|
||||
the header and the real text of the program that is counted in a_text.
|
||||
|
||||
For these machines, define A_TEXT_OFFSET(HDR) to examine the header
|
||||
structure HDR and return the number of bytes to add to `a_text'
|
||||
before writing it (above and beyond the number of bytes of actual
|
||||
program text). HDR's standard fields are already correct, except that
|
||||
this adjustment to the `a_text' field has not yet been made;
|
||||
thus, the amount of offset can depend on the data in the file.
|
||||
|
||||
* A_TEXT_SEEK(HDR)
|
||||
|
||||
If defined, this macro specifies the number of bytes to seek into the
|
||||
a.out file before starting to write the text segment.a
|
||||
|
||||
* EXEC_MAGIC
|
||||
|
||||
For machines using COFF, this macro, if defined, is a value stored
|
||||
into the magic number field of the output file.
|
||||
|
||||
* ADJUST_EXEC_HEADER
|
||||
|
||||
This macro can be used to generate statements to adjust or
|
||||
initialize nonstandard fields in the file header
|
||||
|
||||
* ADDR_CORRECT(ADDR)
|
||||
|
||||
Macro to correct an int which is the bit pattern of a pointer to a byte
|
||||
into an int which is the number of a byte.
|
||||
|
||||
This macro has a default definition which is usually right.
|
||||
This default definition is a no-op on most machines (where a
|
||||
pointer looks like an int) but not on all machines.
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#define PERROR(file) report_error (file, new)
|
||||
|
||||
#include <a.out.h>
|
||||
/* Define getpagesize () if the system does not.
|
||||
Note that this may depend on symbols defined in a.out.h
|
||||
*/
|
||||
#include "getpagesize.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
extern char *start_of_text (); /* Start of text */
|
||||
extern char *start_of_data (); /* Start of initialized data */
|
||||
|
||||
#include <machine/filehdr.h>
|
||||
#include <machine/opthdr.h>
|
||||
#include <machine/scnhdr.h>
|
||||
#include <machine/pte.h>
|
||||
|
||||
static long block_copy_start; /* Old executable start point */
|
||||
static struct filehdr f_hdr; /* File header */
|
||||
static struct opthdr f_ohdr; /* Optional file header (a.out) */
|
||||
long bias; /* Bias to add for growth */
|
||||
#define SYMS_START block_copy_start
|
||||
|
||||
static long text_scnptr;
|
||||
static long data_scnptr;
|
||||
|
||||
static int pagemask;
|
||||
static int pagesz;
|
||||
|
||||
static
|
||||
report_error (file, fd)
|
||||
char *file;
|
||||
int fd;
|
||||
{
|
||||
if (fd)
|
||||
close (fd);
|
||||
error ("Failure operating on %s", file);
|
||||
}
|
||||
|
||||
#define ERROR0(msg) report_error_1 (new, msg, 0, 0); return -1
|
||||
#define ERROR1(msg,x) report_error_1 (new, msg, x, 0); return -1
|
||||
#define ERROR2(msg,x,y) report_error_1 (new, msg, x, y); return -1
|
||||
|
||||
static
|
||||
report_error_1 (fd, msg, a1, a2)
|
||||
int fd;
|
||||
char *msg;
|
||||
int a1, a2;
|
||||
{
|
||||
close (fd);
|
||||
error (msg, a1, a2);
|
||||
}
|
||||
|
||||
/* ****************************************************************
|
||||
* unexec
|
||||
*
|
||||
* driving logic.
|
||||
*/
|
||||
unexec (new_name, a_name, data_start, bss_start, entry_address)
|
||||
char *new_name, *a_name;
|
||||
unsigned data_start, bss_start, entry_address;
|
||||
{
|
||||
int new, a_out = -1;
|
||||
|
||||
if (a_name && (a_out = open (a_name, 0)) < 0) {
|
||||
PERROR (a_name);
|
||||
}
|
||||
if ((new = creat (new_name, 0666)) < 0) {
|
||||
PERROR (new_name);
|
||||
}
|
||||
|
||||
if (make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name) < 0
|
||||
|| copy_text_and_data (new) < 0
|
||||
|| copy_sym (new, a_out, a_name, new_name) < 0 ) {
|
||||
close (new);
|
||||
return -1;
|
||||
}
|
||||
|
||||
close (new);
|
||||
if (a_out >= 0)
|
||||
close (a_out);
|
||||
mark_x (new_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ****************************************************************
|
||||
* make_hdr
|
||||
*
|
||||
* Make the header in the new a.out from the header in core.
|
||||
* Modify the text and data sizes.
|
||||
*/
|
||||
|
||||
struct scnhdr *stbl; /* Table of all scnhdr's */
|
||||
struct scnhdr *f_thdr; /* Text section header */
|
||||
struct scnhdr *f_dhdr; /* Data section header */
|
||||
struct scnhdr *f_tdhdr; /* Thread Data section header */
|
||||
struct scnhdr *f_bhdr; /* Bss section header */
|
||||
struct scnhdr *f_tbhdr; /* Thread Bss section header */
|
||||
|
||||
static int
|
||||
make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name)
|
||||
int new, a_out;
|
||||
unsigned data_start, bss_start, entry_address;
|
||||
char *a_name;
|
||||
char *new_name;
|
||||
{
|
||||
register int scns;
|
||||
unsigned int bss_end;
|
||||
unsigned int eo_data; /* End of initialized data in new exec file */
|
||||
int scntype; /* Section type */
|
||||
int i; /* Var for sorting by vaddr */
|
||||
struct scnhdr scntemp; /* For swapping entries in sort */
|
||||
extern char *start_of_data();
|
||||
|
||||
pagemask = (pagesz = getpagesize()) - 1;
|
||||
|
||||
/* Adjust text/data boundary. */
|
||||
if (!data_start)
|
||||
data_start = (unsigned) start_of_data ();
|
||||
|
||||
data_start = data_start & ~pagemask; /* (Down) to page boundary. */
|
||||
|
||||
bss_end = (sbrk(0) + pagemask) & ~pagemask;
|
||||
|
||||
/* Adjust data/bss boundary. */
|
||||
if (bss_start != 0) {
|
||||
bss_start = (bss_start + pagemask) & ~pagemask;/* (Up) to page bdry. */
|
||||
if (bss_start > bss_end) {
|
||||
ERROR1 ("unexec: Specified bss_start (%x) is past end of program",
|
||||
bss_start);
|
||||
}
|
||||
} else
|
||||
bss_start = bss_end;
|
||||
|
||||
if (data_start > bss_start) { /* Can't have negative data size. */
|
||||
ERROR2 ("unexec: data_start (%x) can't be greater than bss_start (%x)",
|
||||
data_start, bss_start);
|
||||
}
|
||||
|
||||
/* Salvage as much info from the existing file as possible */
|
||||
if (a_out < 0) {
|
||||
ERROR0 ("can't build a COFF file from scratch yet");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
if (read (a_out, &f_hdr, sizeof (f_hdr)) != sizeof (f_hdr)) {
|
||||
PERROR (a_name);
|
||||
}
|
||||
block_copy_start += sizeof (f_hdr);
|
||||
if (f_hdr.h_opthdr > 0) {
|
||||
if (read (a_out, &f_ohdr, sizeof (f_ohdr)) != sizeof (f_ohdr)) {
|
||||
PERROR (a_name);
|
||||
}
|
||||
block_copy_start += sizeof (f_ohdr);
|
||||
}
|
||||
|
||||
/* Allocate room for scn headers */
|
||||
stbl = (struct scnhdr *)malloc( sizeof(struct scnhdr) * f_hdr.h_nscns );
|
||||
if( stbl == NULL ) {
|
||||
ERROR0( "unexec: malloc of stbl failed" );
|
||||
}
|
||||
|
||||
f_tdhdr = f_tbhdr = NULL;
|
||||
|
||||
/* Loop through section headers, copying them in */
|
||||
for (scns = 0; scns < f_hdr.h_nscns; scns++) {
|
||||
|
||||
if( read( a_out, &stbl[scns], sizeof(*stbl)) != sizeof(*stbl)) {
|
||||
PERROR (a_name);
|
||||
}
|
||||
|
||||
scntype = stbl[scns].s_flags & S_TYPMASK; /* What type of section */
|
||||
|
||||
if( stbl[scns].s_scnptr > 0L) {
|
||||
if( block_copy_start < stbl[scns].s_scnptr + stbl[scns].s_size )
|
||||
block_copy_start = stbl[scns].s_scnptr + stbl[scns].s_size;
|
||||
}
|
||||
|
||||
if( scntype == S_TEXT) {
|
||||
f_thdr = &stbl[scns];
|
||||
} else if( scntype == S_DATA) {
|
||||
f_dhdr = &stbl[scns];
|
||||
#ifdef S_TDATA
|
||||
} else if( scntype == S_TDATA ) {
|
||||
f_tdhdr = &stbl[scns];
|
||||
} else if( scntype == S_TBSS ) {
|
||||
f_tbhdr = &stbl[scns];
|
||||
#endif /* S_TDATA (thread stuff) */
|
||||
|
||||
} else if( scntype == S_BSS) {
|
||||
f_bhdr = &stbl[scns];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* We will now convert TEXT and DATA into TEXT, BSS into DATA, and leave
|
||||
* all thread stuff alone.
|
||||
*/
|
||||
|
||||
/* Now we alter the contents of all the f_*hdr variables
|
||||
to correspond to what we want to dump. */
|
||||
|
||||
f_thdr->s_vaddr = (long) start_of_text ();
|
||||
f_thdr->s_size = data_start - f_thdr->s_vaddr;
|
||||
f_thdr->s_scnptr = pagesz;
|
||||
f_thdr->s_relptr = 0;
|
||||
f_thdr->s_nrel = 0;
|
||||
|
||||
eo_data = f_thdr->s_scnptr + f_thdr->s_size;
|
||||
|
||||
if( f_tdhdr ) { /* Process thread data */
|
||||
|
||||
f_tdhdr->s_vaddr = data_start;
|
||||
f_tdhdr->s_size += f_dhdr->s_size - (data_start - f_dhdr->s_vaddr);
|
||||
f_tdhdr->s_scnptr = eo_data;
|
||||
f_tdhdr->s_relptr = 0;
|
||||
f_tdhdr->s_nrel = 0;
|
||||
|
||||
eo_data += f_tdhdr->s_size;
|
||||
|
||||
/* And now for DATA */
|
||||
|
||||
f_dhdr->s_vaddr = f_bhdr->s_vaddr; /* Take BSS start address */
|
||||
f_dhdr->s_size = bss_end - f_bhdr->s_vaddr;
|
||||
f_dhdr->s_scnptr = eo_data;
|
||||
f_dhdr->s_relptr = 0;
|
||||
f_dhdr->s_nrel = 0;
|
||||
|
||||
eo_data += f_dhdr->s_size;
|
||||
|
||||
} else {
|
||||
|
||||
f_dhdr->s_vaddr = data_start;
|
||||
f_dhdr->s_size = bss_start - data_start;
|
||||
f_dhdr->s_scnptr = eo_data;
|
||||
f_dhdr->s_relptr = 0;
|
||||
f_dhdr->s_nrel = 0;
|
||||
|
||||
eo_data += f_dhdr->s_size;
|
||||
|
||||
}
|
||||
|
||||
f_bhdr->s_vaddr = bss_start;
|
||||
f_bhdr->s_size = bss_end - bss_start + pagesz /* fudge */;
|
||||
f_bhdr->s_scnptr = 0;
|
||||
f_bhdr->s_relptr = 0;
|
||||
f_bhdr->s_nrel = 0;
|
||||
|
||||
text_scnptr = f_thdr->s_scnptr;
|
||||
data_scnptr = f_dhdr->s_scnptr;
|
||||
bias = eo_data - block_copy_start;
|
||||
|
||||
if (f_ohdr.o_symptr > 0L) {
|
||||
f_ohdr.o_symptr += bias;
|
||||
}
|
||||
|
||||
if (f_hdr.h_strptr > 0) {
|
||||
f_hdr.h_strptr += bias;
|
||||
}
|
||||
|
||||
if (write (new, &f_hdr, sizeof (f_hdr)) != sizeof (f_hdr)) {
|
||||
PERROR (new_name);
|
||||
}
|
||||
|
||||
if (write (new, &f_ohdr, sizeof (f_ohdr)) != sizeof (f_ohdr)) {
|
||||
PERROR (new_name);
|
||||
}
|
||||
|
||||
for( scns = 0; scns < f_hdr.h_nscns; scns++ ) {
|
||||
|
||||
/* This is a cheesey little loop to write out the section headers
|
||||
* in order of increasing virtual address. Dull but effective.
|
||||
*/
|
||||
|
||||
for( i = scns+1; i < f_hdr.h_nscns; i++ ) {
|
||||
if( stbl[i].s_vaddr < stbl[scns].s_vaddr ) { /* Swap */
|
||||
scntemp = stbl[i];
|
||||
stbl[i] = stbl[scns];
|
||||
stbl[scns] = scntemp;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for( scns = 0; scns < f_hdr.h_nscns; scns++ ) {
|
||||
|
||||
if( write( new, &stbl[scns], sizeof(*stbl)) != sizeof(*stbl)) {
|
||||
PERROR (new_name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return (0);
|
||||
|
||||
}
|
||||
|
||||
/* ****************************************************************
|
||||
* copy_text_and_data
|
||||
*
|
||||
* Copy the text and data segments from memory to the new a.out
|
||||
*/
|
||||
static int
|
||||
copy_text_and_data (new)
|
||||
int new;
|
||||
{
|
||||
register int scns;
|
||||
|
||||
for( scns = 0; scns < f_hdr.h_nscns; scns++ )
|
||||
write_segment( new, &stbl[scns] );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
write_segment( new, sptr )
|
||||
int new;
|
||||
struct scnhdr *sptr;
|
||||
{
|
||||
register char *ptr, *end;
|
||||
register int nwrite, ret;
|
||||
char buf[80];
|
||||
extern int errno;
|
||||
char zeros[128];
|
||||
|
||||
if( sptr->s_scnptr == 0 )
|
||||
return; /* Nothing to do */
|
||||
|
||||
if( lseek( new, (long) sptr->s_scnptr, 0 ) == -1 )
|
||||
PERROR( "unexecing" );
|
||||
|
||||
bzero (zeros, sizeof zeros);
|
||||
|
||||
ptr = (char *) sptr->s_vaddr;
|
||||
end = ptr + sptr->s_size;
|
||||
|
||||
while( ptr < end ) {
|
||||
|
||||
/* distance to next multiple of 128. */
|
||||
nwrite = (((int) ptr + 128) & -128) - (int) ptr;
|
||||
/* But not beyond specified end. */
|
||||
if (nwrite > end - ptr) nwrite = end - ptr;
|
||||
ret = write (new, ptr, nwrite);
|
||||
/* If write gets a page fault, it means we reached
|
||||
a gap between the old text segment and the old data segment.
|
||||
This gap has probably been remapped into part of the text segment.
|
||||
So write zeros for it. */
|
||||
if (ret == -1 && errno == EFAULT)
|
||||
write (new, zeros, nwrite);
|
||||
else if (nwrite != ret) {
|
||||
sprintf (buf,
|
||||
"unexec write failure: addr 0x%x, fileno %d, size 0x%x, wrote 0x%x, errno %d",
|
||||
ptr, new, nwrite, ret, errno);
|
||||
PERROR (buf);
|
||||
}
|
||||
ptr += nwrite;
|
||||
}
|
||||
}
|
||||
|
||||
/* ****************************************************************
|
||||
* copy_sym
|
||||
*
|
||||
* Copy the relocation information and symbol table from the a.out to the new
|
||||
*/
|
||||
static int
|
||||
copy_sym (new, a_out, a_name, new_name)
|
||||
int new, a_out;
|
||||
char *a_name, *new_name;
|
||||
{
|
||||
char page[1024];
|
||||
int n;
|
||||
|
||||
if (a_out < 0)
|
||||
return 0;
|
||||
|
||||
if (SYMS_START == 0L)
|
||||
return 0;
|
||||
|
||||
lseek (a_out, SYMS_START, 0); /* Position a.out to symtab. */
|
||||
lseek( new, (long)f_ohdr.o_symptr, 0 );
|
||||
|
||||
while ((n = read (a_out, page, sizeof page)) > 0) {
|
||||
if (write (new, page, n) != n) {
|
||||
PERROR (new_name);
|
||||
}
|
||||
}
|
||||
if (n < 0) {
|
||||
PERROR (a_name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ****************************************************************
|
||||
* mark_x
|
||||
*
|
||||
* After succesfully building the new a.out, mark it executable
|
||||
*/
|
||||
static
|
||||
mark_x (name)
|
||||
char *name;
|
||||
{
|
||||
struct stat sbuf;
|
||||
int um;
|
||||
int new = 0; /* for PERROR */
|
||||
|
||||
um = umask (777);
|
||||
umask (um);
|
||||
if (stat (name, &sbuf) == -1) {
|
||||
PERROR (name);
|
||||
}
|
||||
sbuf.st_mode |= 0111 & ~um;
|
||||
if (chmod (name, sbuf.st_mode) == -1)
|
||||
PERROR (name);
|
||||
}
|
||||
|
||||
/* Find the first pty letter. This is usually 'p', as in ptyp0, but
|
||||
is sometimes configured down to 'm', 'n', or 'o' for some reason. */
|
||||
|
||||
first_pty_letter ()
|
||||
{
|
||||
struct stat buf;
|
||||
char pty_name[16];
|
||||
char c;
|
||||
|
||||
for (c = 'o'; c >= 'a'; c--)
|
||||
{
|
||||
sprintf (pty_name, "/dev/pty%c0", c);
|
||||
if (stat (pty_name, &buf) < 0)
|
||||
return c + 1;
|
||||
}
|
||||
return 'a';
|
||||
}
|
||||
|
703
src/unexelf.c
Normal file
703
src/unexelf.c
Normal file
@ -0,0 +1,703 @@
|
||||
/* Copyright (C) 1985, 1986, 1987, 1988 Free Software Foundation, Inc.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
|
||||
NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT
|
||||
WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
|
||||
RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS"
|
||||
WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
|
||||
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY
|
||||
AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
|
||||
DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
|
||||
CORRECTION.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
|
||||
STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
|
||||
WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE
|
||||
LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR
|
||||
OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
|
||||
DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR
|
||||
A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS
|
||||
PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
|
||||
|
||||
GENERAL PUBLIC LICENSE TO COPY
|
||||
|
||||
1. You may copy and distribute verbatim copies of this source file
|
||||
as you receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy a valid copyright notice "Copyright
|
||||
(C) 1987 Free Software Foundation, Inc."; and include following the
|
||||
copyright notice a verbatim copy of the above disclaimer of warranty
|
||||
and of this License. You may charge a distribution fee for the
|
||||
physical act of transferring a copy.
|
||||
|
||||
2. You may modify your copy or copies of this source file or
|
||||
any portion of it, and copy and distribute such modifications under
|
||||
the terms of Paragraph 1 above, provided that you also do the following:
|
||||
|
||||
a) cause the modified files to carry prominent notices stating
|
||||
that you changed the files and the date of any change; and
|
||||
|
||||
b) cause the whole of any work that you distribute or publish,
|
||||
that in whole or in part contains or is a derivative of this
|
||||
program or any part thereof, to be licensed at no charge to all
|
||||
third parties on terms identical to those contained in this
|
||||
License Agreement (except that you may choose to grant more extensive
|
||||
warranty protection to some or all third parties, at your option).
|
||||
|
||||
c) You may charge a distribution fee for the physical act of
|
||||
transferring a copy, and you may at your option offer warranty
|
||||
protection in exchange for a fee.
|
||||
|
||||
Mere aggregation of another unrelated program with this program (or its
|
||||
derivative) on a volume of a storage or distribution medium does not bring
|
||||
the other program under the scope of these terms.
|
||||
|
||||
3. You may copy and distribute this program (or a portion or derivative
|
||||
of it, under Paragraph 2) in object code or executable form under the terms
|
||||
of Paragraphs 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of
|
||||
Paragraphs 1 and 2 above; or,
|
||||
|
||||
b) accompany it with a written offer, valid for at least three
|
||||
years, to give any third party free (except for a nominal
|
||||
shipping charge) a complete machine-readable copy of the
|
||||
corresponding source code, to be distributed under the terms of
|
||||
Paragraphs 1 and 2 above; or,
|
||||
|
||||
c) accompany it with the information you received as to where the
|
||||
corresponding source code may be obtained. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form alone.)
|
||||
|
||||
For an executable file, complete source code means all the source code for
|
||||
all modules it contains; but, as a special exception, it need not include
|
||||
source code for modules which are standard libraries that accompany the
|
||||
operating system on which the executable file runs.
|
||||
|
||||
4. You may not copy, sublicense, distribute or transfer this program
|
||||
except as expressly provided under this License Agreement. Any attempt
|
||||
otherwise to copy, sublicense, distribute or transfer this program is void and
|
||||
your rights to use the program under this License agreement shall be
|
||||
automatically terminated. However, parties who have received computer
|
||||
software programs from you with this License Agreement will not have
|
||||
their licenses terminated so long as such parties remain in full compliance.
|
||||
|
||||
5. If you wish to incorporate parts of this program into other free
|
||||
programs whose distribution conditions are different, write to the Free
|
||||
Software Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not yet
|
||||
worked out a simple rule that can be stated here, but we will often permit
|
||||
this. We will be guided by the two goals of preserving the free status of
|
||||
all derivatives of our free software and of promoting the sharing and reuse of
|
||||
software.
|
||||
|
||||
|
||||
In other words, you are welcome to use, share and improve this program.
|
||||
You are forbidden to forbid anyone else to use, share and improve
|
||||
what you give them. Help stamp out software-hoarding! */
|
||||
|
||||
|
||||
/*
|
||||
* unexec.c - Convert a running program into an a.out file.
|
||||
*
|
||||
* Author: Spencer W. Thomas
|
||||
* Computer Science Dept.
|
||||
* University of Utah
|
||||
* Date: Tue Mar 2 1982
|
||||
* Modified heavily since then.
|
||||
*
|
||||
* Synopsis:
|
||||
* unexec (new_name, a_name, data_start, bss_start, entry_address)
|
||||
* char *new_name, *a_name;
|
||||
* unsigned data_start, bss_start, entry_address;
|
||||
*
|
||||
* Takes a snapshot of the program and makes an a.out format file in the
|
||||
* file named by the string argument new_name.
|
||||
* If a_name is non-NULL, the symbol table will be taken from the given file.
|
||||
* On some machines, an existing a_name file is required.
|
||||
*
|
||||
* The boundaries within the a.out file may be adjusted with the data_start
|
||||
* and bss_start arguments. Either or both may be given as 0 for defaults.
|
||||
*
|
||||
* Data_start gives the boundary between the text segment and the data
|
||||
* segment of the program. The text segment can contain shared, read-only
|
||||
* program code and literal data, while the data segment is always unshared
|
||||
* and unprotected. Data_start gives the lowest unprotected address.
|
||||
* The value you specify may be rounded down to a suitable boundary
|
||||
* as required by the machine you are using.
|
||||
*
|
||||
* Specifying zero for data_start means the boundary between text and data
|
||||
* should not be the same as when the program was loaded.
|
||||
* If NO_REMAP is defined, the argument data_start is ignored and the
|
||||
* segment boundaries are never changed.
|
||||
*
|
||||
* Bss_start indicates how much of the data segment is to be saved in the
|
||||
* a.out file and restored when the program is executed. It gives the lowest
|
||||
* unsaved address, and is rounded up to a page boundary. The default when 0
|
||||
* is given assumes that the entire data segment is to be stored, including
|
||||
* the previous data and bss as well as any additional storage allocated with
|
||||
* break (2).
|
||||
*
|
||||
* The new file is set up to start at entry_address.
|
||||
*
|
||||
* If you make improvements I'd like to get them too.
|
||||
* harpo!utah-cs!thomas, thomas@Utah-20
|
||||
*
|
||||
*/
|
||||
|
||||
/* Even more heavily modified by james@bigtex.cactus.org of Dell Computer Co.
|
||||
* ELF support added.
|
||||
*
|
||||
* Basic theory: the data space of the running process needs to be
|
||||
* dumped to the output file. Normally we would just enlarge the size
|
||||
* of .data, scooting everything down. But we can't do that in ELF,
|
||||
* because there is often something between the .data space and the
|
||||
* .bss space.
|
||||
*
|
||||
* In the temacs dump below, notice that the Global Offset Table
|
||||
* (.got) and the Dynamic link data (.dynamic) come between .data1 and
|
||||
* .bss. It does not work to overlap .data with these fields.
|
||||
*
|
||||
* The solution is to create a new .data segment. This segment is
|
||||
* filled with data from the current process. Since the contents of
|
||||
* various sections refer to sections by index, the new .data segment
|
||||
* is made the last in the table to avoid changing any existing index.
|
||||
|
||||
* This is an example of how the section headers are changed. "Addr"
|
||||
* is a process virtual address. "Offset" is a file offset.
|
||||
|
||||
raid:/nfs/raid/src/dist-18.56/src> dump -h temacs
|
||||
|
||||
temacs:
|
||||
|
||||
**** SECTION HEADER TABLE ****
|
||||
[No] Type Flags Addr Offset Size Name
|
||||
Link Info Adralgn Entsize
|
||||
|
||||
[1] 1 2 0x80480d4 0xd4 0x13 .interp
|
||||
0 0 0x1 0
|
||||
|
||||
[2] 5 2 0x80480e8 0xe8 0x388 .hash
|
||||
3 0 0x4 0x4
|
||||
|
||||
[3] 11 2 0x8048470 0x470 0x7f0 .dynsym
|
||||
4 1 0x4 0x10
|
||||
|
||||
[4] 3 2 0x8048c60 0xc60 0x3ad .dynstr
|
||||
0 0 0x1 0
|
||||
|
||||
[5] 9 2 0x8049010 0x1010 0x338 .rel.plt
|
||||
3 7 0x4 0x8
|
||||
|
||||
[6] 1 6 0x8049348 0x1348 0x3 .init
|
||||
0 0 0x4 0
|
||||
|
||||
[7] 1 6 0x804934c 0x134c 0x680 .plt
|
||||
0 0 0x4 0x4
|
||||
|
||||
[8] 1 6 0x80499cc 0x19cc 0x3c56f .text
|
||||
0 0 0x4 0
|
||||
|
||||
[9] 1 6 0x8085f3c 0x3df3c 0x3 .fini
|
||||
0 0 0x4 0
|
||||
|
||||
[10] 1 2 0x8085f40 0x3df40 0x69c .rodata
|
||||
0 0 0x4 0
|
||||
|
||||
[11] 1 2 0x80865dc 0x3e5dc 0xd51 .rodata1
|
||||
0 0 0x4 0
|
||||
|
||||
[12] 1 3 0x8088330 0x3f330 0x20afc .data
|
||||
0 0 0x4 0
|
||||
|
||||
[13] 1 3 0x80a8e2c 0x5fe2c 0x89d .data1
|
||||
0 0 0x4 0
|
||||
|
||||
[14] 1 3 0x80a96cc 0x606cc 0x1a8 .got
|
||||
0 0 0x4 0x4
|
||||
|
||||
[15] 6 3 0x80a9874 0x60874 0x80 .dynamic
|
||||
4 0 0x4 0x8
|
||||
|
||||
[16] 8 3 0x80a98f4 0x608f4 0x449c .bss
|
||||
0 0 0x4 0
|
||||
|
||||
[17] 2 0 0 0x608f4 0x9b90 .symtab
|
||||
18 371 0x4 0x10
|
||||
|
||||
[18] 3 0 0 0x6a484 0x8526 .strtab
|
||||
0 0 0x1 0
|
||||
|
||||
[19] 3 0 0 0x729aa 0x93 .shstrtab
|
||||
0 0 0x1 0
|
||||
|
||||
[20] 1 0 0 0x72a3d 0x68b7 .comment
|
||||
0 0 0x1 0
|
||||
|
||||
raid:/nfs/raid/src/dist-18.56/src> dump -h xemacs
|
||||
|
||||
xemacs:
|
||||
|
||||
**** SECTION HEADER TABLE ****
|
||||
[No] Type Flags Addr Offset Size Name
|
||||
Link Info Adralgn Entsize
|
||||
|
||||
[1] 1 2 0x80480d4 0xd4 0x13 .interp
|
||||
0 0 0x1 0
|
||||
|
||||
[2] 5 2 0x80480e8 0xe8 0x388 .hash
|
||||
3 0 0x4 0x4
|
||||
|
||||
[3] 11 2 0x8048470 0x470 0x7f0 .dynsym
|
||||
4 1 0x4 0x10
|
||||
|
||||
[4] 3 2 0x8048c60 0xc60 0x3ad .dynstr
|
||||
0 0 0x1 0
|
||||
|
||||
[5] 9 2 0x8049010 0x1010 0x338 .rel.plt
|
||||
3 7 0x4 0x8
|
||||
|
||||
[6] 1 6 0x8049348 0x1348 0x3 .init
|
||||
0 0 0x4 0
|
||||
|
||||
[7] 1 6 0x804934c 0x134c 0x680 .plt
|
||||
0 0 0x4 0x4
|
||||
|
||||
[8] 1 6 0x80499cc 0x19cc 0x3c56f .text
|
||||
0 0 0x4 0
|
||||
|
||||
[9] 1 6 0x8085f3c 0x3df3c 0x3 .fini
|
||||
0 0 0x4 0
|
||||
|
||||
[10] 1 2 0x8085f40 0x3df40 0x69c .rodata
|
||||
0 0 0x4 0
|
||||
|
||||
[11] 1 2 0x80865dc 0x3e5dc 0xd51 .rodata1
|
||||
0 0 0x4 0
|
||||
|
||||
[12] 1 3 0x8088330 0x3f330 0x20afc .data
|
||||
0 0 0x4 0
|
||||
|
||||
[13] 1 3 0x80a8e2c 0x5fe2c 0x89d .data1
|
||||
0 0 0x4 0
|
||||
|
||||
[14] 1 3 0x80a96cc 0x606cc 0x1a8 .got
|
||||
0 0 0x4 0x4
|
||||
|
||||
[15] 6 3 0x80a9874 0x60874 0x80 .dynamic
|
||||
4 0 0x4 0x8
|
||||
|
||||
[16] 8 3 0x80c6800 0x7d800 0 .bss
|
||||
0 0 0x4 0
|
||||
|
||||
[17] 2 0 0 0x7d800 0x9b90 .symtab
|
||||
18 371 0x4 0x10
|
||||
|
||||
[18] 3 0 0 0x87390 0x8526 .strtab
|
||||
0 0 0x1 0
|
||||
|
||||
[19] 3 0 0 0x8f8b6 0x93 .shstrtab
|
||||
0 0 0x1 0
|
||||
|
||||
[20] 1 0 0 0x8f949 0x68b7 .comment
|
||||
0 0 0x1 0
|
||||
|
||||
[21] 1 3 0x80a98f4 0x608f4 0x1cf0c .data
|
||||
0 0 0x4 0
|
||||
|
||||
* This is an example of how the file header is changed. "Shoff" is
|
||||
* the section header offset within the file. Since that table is
|
||||
* after the new .data section, it is moved. "Shnum" is the number of
|
||||
* sections, which we increment.
|
||||
*
|
||||
* "Phoff" is the file offset to the program header. "Phentsize" and
|
||||
* "Shentsz" are the program and section header entries sizes respectively.
|
||||
* These can be larger than the apparent struct sizes.
|
||||
|
||||
raid:/nfs/raid/src/dist-18.56/src> dump -f temacs
|
||||
|
||||
temacs:
|
||||
|
||||
**** ELF HEADER ****
|
||||
Class Data Type Machine Version
|
||||
Entry Phoff Shoff Flags Ehsize
|
||||
Phentsize Phnum Shentsz Shnum Shstrndx
|
||||
|
||||
1 1 2 3 1
|
||||
0x80499cc 0x34 0x792f4 0 0x34
|
||||
0x20 5 0x28 21 19
|
||||
|
||||
raid:/nfs/raid/src/dist-18.56/src> dump -f xemacs
|
||||
|
||||
xemacs:
|
||||
|
||||
**** ELF HEADER ****
|
||||
Class Data Type Machine Version
|
||||
Entry Phoff Shoff Flags Ehsize
|
||||
Phentsize Phnum Shentsz Shnum Shstrndx
|
||||
|
||||
1 1 2 3 1
|
||||
0x80499cc 0x34 0x96200 0 0x34
|
||||
0x20 5 0x28 22 19
|
||||
|
||||
* These are the program headers. "Offset" is the file offset to the
|
||||
* segment. "Vaddr" is the memory load address. "Filesz" is the
|
||||
* segment size as it appears in the file, and "Memsz" is the size in
|
||||
* memory. Below, the third segment is the code and the fourth is the
|
||||
* data: the difference between Filesz and Memsz is .bss
|
||||
|
||||
raid:/nfs/raid/src/dist-18.56/src> dump -o temacs
|
||||
|
||||
temacs:
|
||||
***** PROGRAM EXECUTION HEADER *****
|
||||
Type Offset Vaddr Paddr
|
||||
Filesz Memsz Flags Align
|
||||
|
||||
6 0x34 0x8048034 0
|
||||
0xa0 0xa0 5 0
|
||||
|
||||
3 0xd4 0 0
|
||||
0x13 0 4 0
|
||||
|
||||
1 0x34 0x8048034 0
|
||||
0x3f2f9 0x3f2f9 5 0x1000
|
||||
|
||||
1 0x3f330 0x8088330 0
|
||||
0x215c4 0x25a60 7 0x1000
|
||||
|
||||
2 0x60874 0x80a9874 0
|
||||
0x80 0 7 0
|
||||
|
||||
raid:/nfs/raid/src/dist-18.56/src> dump -o xemacs
|
||||
|
||||
xemacs:
|
||||
***** PROGRAM EXECUTION HEADER *****
|
||||
Type Offset Vaddr Paddr
|
||||
Filesz Memsz Flags Align
|
||||
|
||||
6 0x34 0x8048034 0
|
||||
0xa0 0xa0 5 0
|
||||
|
||||
3 0xd4 0 0
|
||||
0x13 0 4 0
|
||||
|
||||
1 0x34 0x8048034 0
|
||||
0x3f2f9 0x3f2f9 5 0x1000
|
||||
|
||||
1 0x3f330 0x8088330 0
|
||||
0x3e4d0 0x3e4d0 7 0x1000
|
||||
|
||||
2 0x60874 0x80a9874 0
|
||||
0x80 0 7 0
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <elf.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#ifndef emacs
|
||||
#define fatal(a, b, c) fprintf(stderr, a, b, c), exit(1)
|
||||
#else
|
||||
extern void fatal(char *, ...);
|
||||
#endif
|
||||
|
||||
/* Get the address of a particular section or program header entry,
|
||||
* accounting for the size of the entries.
|
||||
*/
|
||||
|
||||
#define OLD_SECTION_H(n) \
|
||||
(*(Elf32_Shdr *) ((byte *) old_section_h + old_file_h->e_shentsize * (n)))
|
||||
#define NEW_SECTION_H(n) \
|
||||
(*(Elf32_Shdr *) ((byte *) new_section_h + new_file_h->e_shentsize * (n)))
|
||||
#define OLD_PROGRAM_H(n) \
|
||||
(*(Elf32_Phdr *) ((byte *) old_program_h + old_file_h->e_phentsize * (n)))
|
||||
#define NEW_PROGRAM_H(n) \
|
||||
(*(Elf32_Phdr *) ((byte *) new_program_h + new_file_h->e_phentsize * (n)))
|
||||
|
||||
typedef unsigned char byte;
|
||||
|
||||
/* ****************************************************************
|
||||
* unexec
|
||||
*
|
||||
* driving logic.
|
||||
*
|
||||
* In ELF, this works by replacing the old .bss section with a new
|
||||
* .data section, and inserting an empty .bss immediately afterwards.
|
||||
*
|
||||
*/
|
||||
void
|
||||
unexec (new_name, old_name, data_start, bss_start, entry_address)
|
||||
char *new_name, *old_name;
|
||||
unsigned data_start, bss_start, entry_address;
|
||||
{
|
||||
extern unsigned int bss_end;
|
||||
int new_file, old_file, new_file_size;
|
||||
|
||||
/* Pointers to the base of the image of the two files. */
|
||||
caddr_t old_base, new_base;
|
||||
|
||||
/* Pointers to the file, program and section headers for the old and new
|
||||
* files.
|
||||
*/
|
||||
Elf32_Ehdr *old_file_h, *new_file_h;
|
||||
Elf32_Phdr *old_program_h, *new_program_h;
|
||||
Elf32_Shdr *old_section_h, *new_section_h;
|
||||
|
||||
/* Point to the section name table in the old file */
|
||||
char *old_section_names;
|
||||
|
||||
Elf32_Addr old_bss_addr, new_bss_addr;
|
||||
Elf32_Word old_bss_size, new_data2_size;
|
||||
Elf32_Off new_data2_offset;
|
||||
Elf32_Addr new_data2_addr;
|
||||
|
||||
int n, old_bss_index, old_data_index, new_data2_index;
|
||||
struct stat stat_buf;
|
||||
|
||||
/* Open the old file & map it into the address space. */
|
||||
|
||||
old_file = open (old_name, O_RDONLY);
|
||||
|
||||
if (old_file < 0)
|
||||
fatal ("Can't open %s for reading: errno %d\n", old_name, errno);
|
||||
|
||||
if (fstat (old_file, &stat_buf) == -1)
|
||||
fatal ("Can't fstat(%s): errno %d\n", old_name, errno);
|
||||
|
||||
old_base = mmap (0, stat_buf.st_size, PROT_READ, MAP_SHARED, old_file, 0);
|
||||
|
||||
if (old_base == (caddr_t) -1)
|
||||
fatal ("Can't mmap(%s): errno %d\n", old_name, errno);
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "mmap(%s, %x) -> %x\n", old_name, stat_buf.st_size,
|
||||
old_base);
|
||||
#endif
|
||||
|
||||
/* Get pointers to headers & section names */
|
||||
|
||||
old_file_h = (Elf32_Ehdr *) old_base;
|
||||
old_program_h = (Elf32_Phdr *) ((byte *) old_base + old_file_h->e_phoff);
|
||||
old_section_h = (Elf32_Shdr *) ((byte *) old_base + old_file_h->e_shoff);
|
||||
old_section_names = (char *) old_base
|
||||
+ OLD_SECTION_H(old_file_h->e_shstrndx).sh_offset;
|
||||
|
||||
/* Find the old .bss section. Figure out parameters of the new
|
||||
* data2 and bss sections.
|
||||
*/
|
||||
|
||||
for (old_bss_index = 1; old_bss_index < old_file_h->e_shnum; old_bss_index++)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "Looking for .bss - found %s\n",
|
||||
old_section_names + OLD_SECTION_H(old_bss_index).sh_name);
|
||||
#endif
|
||||
if (!strcmp (old_section_names + OLD_SECTION_H(old_bss_index).sh_name,
|
||||
".bss"))
|
||||
break;
|
||||
}
|
||||
if (old_bss_index == old_file_h->e_shnum)
|
||||
fatal ("Can't find .bss in %s.\n", old_name, 0);
|
||||
|
||||
old_bss_addr = OLD_SECTION_H(old_bss_index).sh_addr;
|
||||
old_bss_size = OLD_SECTION_H(old_bss_index).sh_size;
|
||||
#if defined(emacs) || !defined(DEBUG)
|
||||
bss_end = (unsigned int) sbrk (0);
|
||||
new_bss_addr = (Elf32_Addr) bss_end;
|
||||
#else
|
||||
new_bss_addr = old_bss_addr + old_bss_size + 0x1234;
|
||||
#endif
|
||||
new_data2_addr = old_bss_addr;
|
||||
new_data2_size = new_bss_addr - old_bss_addr;
|
||||
new_data2_offset = OLD_SECTION_H(old_bss_index).sh_offset;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "old_bss_index %d\n", old_bss_index);
|
||||
fprintf (stderr, "old_bss_addr %x\n", old_bss_addr);
|
||||
fprintf (stderr, "old_bss_size %x\n", old_bss_size);
|
||||
fprintf (stderr, "new_bss_addr %x\n", new_bss_addr);
|
||||
fprintf (stderr, "new_data2_addr %x\n", new_data2_addr);
|
||||
fprintf (stderr, "new_data2_size %x\n", new_data2_size);
|
||||
fprintf (stderr, "new_data2_offset %x\n", new_data2_offset);
|
||||
#endif
|
||||
|
||||
if ((unsigned) new_bss_addr < (unsigned) old_bss_addr + old_bss_size)
|
||||
fatal (".bss shrank when undumping???\n", 0, 0);
|
||||
|
||||
/* Set the output file to the right size and mmap(2) it. Set
|
||||
* pointers to various interesting objects. stat_buf still has
|
||||
* old_file data.
|
||||
*/
|
||||
|
||||
new_file = open (new_name, O_RDWR | O_CREAT, 0666);
|
||||
if (new_file < 0)
|
||||
fatal ("Can't creat(%s): errno %d\n", new_name, errno);
|
||||
|
||||
new_file_size = stat_buf.st_size + old_file_h->e_shentsize + new_data2_size;
|
||||
|
||||
if (ftruncate (new_file, new_file_size))
|
||||
fatal ("Can't ftruncate(%s): errno %d\n", new_name, errno);
|
||||
|
||||
new_base = mmap (0, new_file_size, PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
new_file, 0);
|
||||
|
||||
if (new_base == (caddr_t) -1)
|
||||
fatal ("Can't mmap(%s): errno %d\n", new_name, errno);
|
||||
|
||||
new_file_h = (Elf32_Ehdr *) new_base;
|
||||
new_program_h = (Elf32_Phdr *) ((byte *) new_base + old_file_h->e_phoff);
|
||||
new_section_h = (Elf32_Shdr *)
|
||||
((byte *) new_base + old_file_h->e_shoff + new_data2_size);
|
||||
|
||||
/* Make our new file, program and section headers as copies of the
|
||||
* originals.
|
||||
*/
|
||||
|
||||
memcpy (new_file_h, old_file_h, old_file_h->e_ehsize);
|
||||
memcpy (new_program_h, old_program_h,
|
||||
old_file_h->e_phnum * old_file_h->e_phentsize);
|
||||
memcpy (new_section_h, old_section_h,
|
||||
old_file_h->e_shnum * old_file_h->e_shentsize);
|
||||
|
||||
/* Fix up file header. We'll add one section. Section header is
|
||||
* further away now.
|
||||
*/
|
||||
|
||||
new_file_h->e_shoff += new_data2_size;
|
||||
new_file_h->e_shnum += 1;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "Old section offset %x\n", old_file_h->e_shoff);
|
||||
fprintf (stderr, "Old section count %d\n", old_file_h->e_shnum);
|
||||
fprintf (stderr, "New section offset %x\n", new_file_h->e_shoff);
|
||||
fprintf (stderr, "New section count %d\n", new_file_h->e_shnum);
|
||||
#endif
|
||||
|
||||
/* Fix up a new program header. Extend the writable data segment so
|
||||
* that the bss area is covered too. Find that segment by looking
|
||||
* for a segment that ends just before the .bss area. Make sure
|
||||
* that no segments are above the new .data2. Put a loop at the end
|
||||
* to adjust the offset and address of any segment that is above
|
||||
* data2, just in case we decide to allow this later.
|
||||
*/
|
||||
|
||||
for (n = new_file_h->e_phnum - 1; n >= 0; n--)
|
||||
{
|
||||
if (NEW_PROGRAM_H(n).p_vaddr + NEW_PROGRAM_H(n).p_filesz > old_bss_addr)
|
||||
fatal ("Program segment above .bss in %s\n", old_name, 0);
|
||||
|
||||
if (NEW_PROGRAM_H(n).p_type == PT_LOAD
|
||||
&& (NEW_PROGRAM_H(n).p_vaddr + NEW_PROGRAM_H(n).p_filesz
|
||||
== old_bss_addr))
|
||||
break;
|
||||
}
|
||||
if (n < 0)
|
||||
fatal ("Couldn't find segment next to .bss in %s\n", old_name, 0);
|
||||
|
||||
NEW_PROGRAM_H(n).p_filesz += new_data2_size;
|
||||
NEW_PROGRAM_H(n).p_memsz = NEW_PROGRAM_H(n).p_filesz;
|
||||
|
||||
#if 0 /* Maybe allow section after data2 - does this ever happen? */
|
||||
for (n = new_file_h->e_phnum - 1; n >= 0; n--)
|
||||
{
|
||||
if (NEW_PROGRAM_H(n).p_vaddr
|
||||
&& NEW_PROGRAM_H(n).p_vaddr >= new_data2_addr)
|
||||
NEW_PROGRAM_H(n).p_vaddr += new_data2_size - old_bss_size;
|
||||
|
||||
if (NEW_PROGRAM_H(n).p_offset >= new_data2_offset)
|
||||
NEW_PROGRAM_H(n).p_offset += new_data2_size;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Fix up section headers based on new .data2 section. Any section
|
||||
* whose offset or virtual address is after the new .data2 section
|
||||
* gets its value adjusted. .bss size becomes zero and new address
|
||||
* is set. data2 section header gets added by copying the existing
|
||||
* .data header and modifying the offset, address and size.
|
||||
*/
|
||||
|
||||
for (n = 1; n < new_file_h->e_shnum; n++)
|
||||
{
|
||||
if (NEW_SECTION_H(n).sh_offset >= new_data2_offset)
|
||||
NEW_SECTION_H(n).sh_offset += new_data2_size;
|
||||
|
||||
if (NEW_SECTION_H(n).sh_addr
|
||||
&& NEW_SECTION_H(n).sh_addr >= new_data2_addr)
|
||||
NEW_SECTION_H(n).sh_addr += new_data2_size - old_bss_size;
|
||||
}
|
||||
|
||||
new_data2_index = old_file_h->e_shnum;
|
||||
|
||||
for (old_data_index = 1; old_data_index < old_file_h->e_shnum;
|
||||
old_data_index++)
|
||||
if (!strcmp (old_section_names + OLD_SECTION_H(old_data_index).sh_name,
|
||||
".data"))
|
||||
break;
|
||||
if (old_data_index == old_file_h->e_shnum)
|
||||
fatal ("Can't find .data in %s.\n", old_name, 0);
|
||||
|
||||
memcpy (&NEW_SECTION_H(new_data2_index), &OLD_SECTION_H(old_data_index),
|
||||
new_file_h->e_shentsize);
|
||||
|
||||
NEW_SECTION_H(new_data2_index).sh_addr = new_data2_addr;
|
||||
NEW_SECTION_H(new_data2_index).sh_offset = new_data2_offset;
|
||||
NEW_SECTION_H(new_data2_index).sh_size = new_data2_size;
|
||||
|
||||
NEW_SECTION_H(old_bss_index).sh_size = 0;
|
||||
NEW_SECTION_H(old_bss_index).sh_addr = new_data2_addr + new_data2_size;
|
||||
|
||||
/* Write out the sections. .data and .data1 (and data2, called
|
||||
* ".data" in the strings table) get copied from the current process
|
||||
* instead of the old file.
|
||||
*/
|
||||
|
||||
for (n = new_file_h->e_shnum - 1; n; n--)
|
||||
{
|
||||
caddr_t src;
|
||||
|
||||
if (NEW_SECTION_H(n).sh_type == SHT_NULL
|
||||
|| NEW_SECTION_H(n).sh_type == SHT_NOBITS)
|
||||
continue;
|
||||
|
||||
if (!strcmp (old_section_names + NEW_SECTION_H(n).sh_name, ".data")
|
||||
|| !strcmp ((old_section_names + NEW_SECTION_H(n).sh_name),
|
||||
".data1"))
|
||||
src = (caddr_t) NEW_SECTION_H(n).sh_addr;
|
||||
else
|
||||
src = old_base + OLD_SECTION_H(n).sh_offset;
|
||||
|
||||
memcpy (NEW_SECTION_H(n).sh_offset + new_base, src,
|
||||
NEW_SECTION_H(n).sh_size);
|
||||
}
|
||||
|
||||
/* Close the files and make the new file executable */
|
||||
|
||||
if (close (old_file))
|
||||
fatal ("Can't close(%s): errno %d\n", old_name, errno);
|
||||
|
||||
if (close (new_file))
|
||||
fatal ("Can't close(%s): errno %d\n", new_name, errno);
|
||||
|
||||
if (stat (new_name, &stat_buf) == -1)
|
||||
fatal ("Can't stat(%s): errno %d\n", new_name, errno);
|
||||
|
||||
n = umask (777);
|
||||
umask (n);
|
||||
stat_buf.st_mode |= 0111 & ~n;
|
||||
if (chmod (new_name, stat_buf.st_mode) == -1)
|
||||
fatal ("Can't chmod(%s): errno %d\n", new_name, errno);
|
||||
}
|
262
src/unexenix.c
Normal file
262
src/unexenix.c
Normal file
@ -0,0 +1,262 @@
|
||||
/* Unexec for Xenix.
|
||||
Note that the GNU project considers support for Xenix operation
|
||||
a peripheral activity which should not be allowed to divert effort
|
||||
from development of the GNU system. Changes in this code will be
|
||||
installed when Xenix users send them in, but aside from that
|
||||
we don't plan to think about it, or about whether other Emacs
|
||||
maintenance might break it.
|
||||
|
||||
Copyright (C) 1988 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Emacs is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Emacs; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
On 80386 Xenix, segmentation screws prevent us from modifying the text
|
||||
segment at all. We basically just plug a new value for "data segment
|
||||
size" into the countless headers and copy the other records straight
|
||||
through. The data segment is ORG'ed at the xs_rbase value of the data
|
||||
segment's xseg record (always @ 0x1880000, thanks to the "sophisticated
|
||||
memory management hardware" of the chip) and extends to sbrk(0), exactly.
|
||||
This code is afraid to malloc (should it be?), and alloca has to be the
|
||||
wimpy, malloc-based version; consequently, data is usually copied in
|
||||
smallish chunks.
|
||||
|
||||
gb@entity.com
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <varargs.h>
|
||||
#include <a.out.h>
|
||||
|
||||
static void fatal_unexec ();
|
||||
|
||||
#define READ(_fd, _buffer, _size, _error_message, _error_arg) \
|
||||
errno = EEOF; \
|
||||
if (read(_fd, _buffer, _size) != _size) \
|
||||
fatal_unexec(_error_message, _error_arg);
|
||||
|
||||
#define WRITE(_fd, _buffer, _size, _error_message, _error_arg) \
|
||||
if (write(_fd, _buffer, _size) != _size) \
|
||||
fatal_unexec(_error_message, _error_arg);
|
||||
|
||||
#define SEEK(_fd, _position, _error_message, _error_arg) \
|
||||
errno = EEOF; \
|
||||
if (lseek(_fd, _position, L_SET) != _position) \
|
||||
fatal_unexec(_error_message, _error_arg);
|
||||
|
||||
extern int errno;
|
||||
extern int sys_nerr;
|
||||
extern char *sys_errlist[];
|
||||
#define EEOF -1
|
||||
|
||||
#ifndef L_SET
|
||||
#define L_SET 0
|
||||
#endif
|
||||
|
||||
/* Should check the magic number of the old executable;
|
||||
not yet written. */
|
||||
check_exec (x)
|
||||
struct xexec *x;
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
unexec (new_name, a_name, data_start, bss_start, entry_address)
|
||||
char *new_name, *a_name;
|
||||
unsigned data_start, bss_start, entry_address;
|
||||
{
|
||||
char *sbrk (), *datalim = sbrk (0), *data_org;
|
||||
long segpos, textseen, textpos, textlen, datapos, datadiff, datalen;
|
||||
|
||||
struct xexec u_xexec, /* a.out header */
|
||||
*u_xexecp = &u_xexec;
|
||||
struct xext u_xext, /* extended header */
|
||||
*u_xextp = &u_xext;
|
||||
struct xseg u_xseg, /* segment table entry */
|
||||
*u_xsegp = &u_xseg;
|
||||
int i, nsegs, isdata = 0, infd, outfd;
|
||||
|
||||
infd = open (a_name, O_RDONLY, 0);
|
||||
if (infd < 0) fatal_unexec ("opening %s", a_name);
|
||||
|
||||
outfd = creat (new_name, 0666);
|
||||
if (outfd < 0) fatal_unexec ("creating %s", new_name);
|
||||
|
||||
READ (infd, u_xexecp, sizeof (struct xexec),
|
||||
"error reading %s", a_name);
|
||||
check_exec (u_xexecp);
|
||||
READ (infd, u_xextp, sizeof (struct xext),
|
||||
"error reading %s", a_name);
|
||||
segpos = u_xextp->xe_segpos;
|
||||
nsegs = u_xextp->xe_segsize / sizeof (struct xseg);
|
||||
SEEK (infd, segpos, "seek error on %s", a_name);
|
||||
for (i = 0; i < nsegs; i ++)
|
||||
{
|
||||
READ (infd, u_xsegp, sizeof (struct xseg),
|
||||
"error reading %s", a_name);
|
||||
switch (u_xsegp->xs_type)
|
||||
{
|
||||
case XS_TTEXT:
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
textpos = u_xsegp->xs_filpos;
|
||||
textlen = u_xsegp->xs_psize;
|
||||
break;
|
||||
}
|
||||
fatal_unexec ("invalid text segment in %s", a_name);
|
||||
}
|
||||
case XS_TDATA:
|
||||
{
|
||||
if (i == 1)
|
||||
{
|
||||
datapos = u_xsegp->xs_filpos;
|
||||
datalen = datalim - (data_org = (char *)(u_xsegp->xs_rbase));
|
||||
datadiff = datalen - u_xsegp->xs_psize;
|
||||
break;
|
||||
}
|
||||
fatal_unexec ("invalid data segment in %s", a_name);
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (i > 1) break;
|
||||
fatal_unexec ("invalid segment record in %s", a_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
u_xexecp->x_data = datalen;
|
||||
u_xexecp->x_bss = 0;
|
||||
WRITE (outfd, u_xexecp, sizeof (struct xexec),
|
||||
"error writing %s", new_name);
|
||||
WRITE (outfd, u_xextp, sizeof (struct xext),
|
||||
"error writing %s", new_name);
|
||||
SEEK (infd, segpos, "seek error on %s", a_name);
|
||||
SEEK (outfd, segpos, "seek error on %s", new_name);
|
||||
|
||||
/* Copy the text segment record verbatim. */
|
||||
|
||||
copyrec (infd, outfd, sizeof (struct xseg), a_name, new_name);
|
||||
|
||||
/* Read, modify, write the data segment record. */
|
||||
|
||||
READ (infd, u_xsegp, sizeof (struct xseg),
|
||||
"error reading %s", a_name);
|
||||
u_xsegp->xs_psize = u_xsegp->xs_vsize = datalen;
|
||||
u_xsegp->xs_attr &= (~XS_AITER & ~XS_ABSS);
|
||||
WRITE (outfd, u_xsegp, sizeof (struct xseg),
|
||||
"error writing %s", new_name);
|
||||
|
||||
/* Now copy any additional segment records, adjusting their
|
||||
file position field */
|
||||
|
||||
for (i = 2; i < nsegs; i++)
|
||||
{
|
||||
READ (infd, u_xsegp, sizeof (struct xseg),
|
||||
"error reading %s", a_name);
|
||||
u_xsegp->xs_filpos += datadiff;
|
||||
WRITE (outfd, u_xsegp, sizeof (struct xseg),
|
||||
"error writing %s", new_name);
|
||||
}
|
||||
|
||||
SEEK (infd, textpos, "seek error on %s", a_name);
|
||||
SEEK (outfd, textpos, "seek error on %s", new_name);
|
||||
copyrec (infd, outfd, textlen, a_name, new_name);
|
||||
|
||||
SEEK (outfd, datapos, "seek error on %s", new_name);
|
||||
WRITE (outfd, data_org, datalen,
|
||||
"write error on %s", new_name);
|
||||
|
||||
for (i = 2, segpos += (2 * sizeof (struct xseg));
|
||||
i < nsegs;
|
||||
i++, segpos += sizeof (struct xseg))
|
||||
{
|
||||
SEEK (infd, segpos, "seek error on %s", a_name);
|
||||
READ (infd, u_xsegp, sizeof (struct xseg),
|
||||
"read error on %s", a_name);
|
||||
SEEK (infd, u_xsegp->xs_filpos, "seek error on %s", a_name);
|
||||
/* We should be at eof in the output file here, but we must seek
|
||||
because the xs_filpos and xs_psize fields in symbol table
|
||||
segments are inconsistent. */
|
||||
SEEK (outfd, u_xsegp->xs_filpos + datadiff, "seek error on %s", new_name);
|
||||
copyrec (infd, outfd, u_xsegp->xs_psize, a_name, new_name);
|
||||
}
|
||||
close (infd);
|
||||
close (outfd);
|
||||
mark_x (new_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
copyrec (infd, outfd, len, in_name, out_name)
|
||||
int infd, outfd, len;
|
||||
char *in_name, *out_name;
|
||||
{
|
||||
char buf[BUFSIZ];
|
||||
int chunk;
|
||||
|
||||
while (len)
|
||||
{
|
||||
chunk = BUFSIZ;
|
||||
if (chunk > len)
|
||||
chunk = len;
|
||||
READ (infd, buf, chunk, "error reading %s", in_name);
|
||||
WRITE (outfd, buf, chunk, "error writing %s", out_name);
|
||||
len -= chunk;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* mark_x
|
||||
*
|
||||
* After succesfully building the new a.out, mark it executable
|
||||
*/
|
||||
static
|
||||
mark_x (name)
|
||||
char *name;
|
||||
{
|
||||
struct stat sbuf;
|
||||
int um = umask (777);
|
||||
umask (um);
|
||||
if (stat (name, &sbuf) < 0)
|
||||
fatal_unexec ("getting protection on %s", name);
|
||||
sbuf.st_mode |= 0111 & ~um;
|
||||
if (chmod (name, sbuf.st_mode) < 0)
|
||||
fatal_unexec ("setting protection on %s", name);
|
||||
}
|
||||
|
||||
static void
|
||||
fatal_unexec (s, va_alist)
|
||||
va_dcl
|
||||
{
|
||||
va_list ap;
|
||||
if (errno == EEOF)
|
||||
fputs ("unexec: unexpected end of file, ", stderr);
|
||||
else if (errno < sys_nerr)
|
||||
fprintf (stderr, "unexec: %s, ", sys_errlist[errno]);
|
||||
else
|
||||
fprintf (stderr, "unexec: error code %d, ", errno);
|
||||
va_start (ap);
|
||||
_doprnt (s, ap, stderr);
|
||||
fputs (".\n", stderr);
|
||||
exit (1);
|
||||
}
|
@ -60,6 +60,7 @@ unexec(new_name, old_name, new_end_of_text, dummy1, dummy2)
|
||||
int old_size, new_size;
|
||||
struct header hdr;
|
||||
struct som_exec_auxhdr auxhdr;
|
||||
long i;
|
||||
|
||||
/* For the greatest flexibility, should create a temporary file in
|
||||
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)
|
||||
|
||||
/* Decide how large the new and old data areas are */
|
||||
old_size = auxhdr.exec_dsize;
|
||||
new_size = sbrk(0) - auxhdr.exec_dmem;
|
||||
/* I suspect these two statements are separate
|
||||
to avoid a compiler bug in hpux version 8. */
|
||||
i = sbrk (0);
|
||||
new_size = i - auxhdr.exec_dmem;
|
||||
|
||||
/* Copy the old file to the new, up to the data space */
|
||||
lseek(old, 0, 0);
|
||||
|
2
src/vlimit.h
Normal file
2
src/vlimit.h
Normal file
@ -0,0 +1,2 @@
|
||||
/* Dummy for Emacs so that we can run on VMS... */
|
||||
#define LIM_DATA 0
|
@ -16,7 +16,7 @@ GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Emacs; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*
|
||||
* Usage:
|
||||
|
34
src/vms-pwd.h
Normal file
34
src/vms-pwd.h
Normal file
@ -0,0 +1,34 @@
|
||||
/* GNU Emacs password definition file.
|
||||
Copyright (C) 1986 Free Software Foundation.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Emacs is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Emacs; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifdef VMS
|
||||
/* On VMS, we read the UAF file and emulate some of the necessary
|
||||
fields for Emacs. */
|
||||
#include "uaf.h"
|
||||
|
||||
struct passwd {
|
||||
char pw_name[UAF$S_USERNAME+1];
|
||||
char pw_passwd[UAF$S_PWD];
|
||||
short pw_uid;
|
||||
short pw_gid;
|
||||
char pw_gecos[UAF$S_OWNER+1];
|
||||
char pw_dir[UAF$S_DEFDEV+UAF$S_DEFDIR+1];
|
||||
char pw_shell[UAF$S_DEFCLI+1];
|
||||
};
|
||||
#endif /* VMS */
|
97
src/vmsdir.h
Normal file
97
src/vmsdir.h
Normal file
@ -0,0 +1,97 @@
|
||||
/* GNU Emacs VMS directory definition file.
|
||||
Copyright (C) 1986 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Emacs is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Emacs; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/*
|
||||
* Files-11 Ver. 2 directory structure (VMS V4.x - long names)
|
||||
*/
|
||||
#ifndef DIR$K_LENGTH
|
||||
|
||||
#define DIR$C_FID 0
|
||||
#define DIR$C_LINKNAME 1
|
||||
#define DIR$K_LENGTH 6
|
||||
#define DIR$C_LENGTH 6
|
||||
#define DIR$S_DIRDEF 6
|
||||
#define DIR$W_SIZE 0
|
||||
#define DIR$W_VERLIMIT 2
|
||||
#define DIR$B_FLAGS 4
|
||||
#define DIR$S_TYPE 3
|
||||
#define DIR$V_TYPE 0
|
||||
#define DIR$V_NEXTREC 6
|
||||
#define DIR$V_PREVREC 7
|
||||
#define DIR$B_NAMECOUNT 5
|
||||
#define DIR$S_NAME 80
|
||||
#define DIR$T_NAME 6
|
||||
|
||||
#define DIR$K_VERSION 8
|
||||
#define DIR$C_VERSION 8
|
||||
#define DIR$S_DIRDEF1 8
|
||||
#define DIR$W_VERSION 0
|
||||
#define DIR$S_FID 6
|
||||
#define DIR$W_FID 2
|
||||
#define DIR$W_FID_NUM 2
|
||||
#define DIR$W_FID_SEQ 4
|
||||
#define DIR$W_FID_RVN 6
|
||||
#define DIR$B_FID_RVN 6
|
||||
#define DIR$B_FID_NMX 7
|
||||
|
||||
#define DIR$S_DIRDEF2 1
|
||||
#define DIR$T_LINKNAME 0
|
||||
|
||||
typedef struct dir$_name {
|
||||
/* short dir$w_size; /* if you read with RMS, it eats this... */
|
||||
short dir$w_verlimit; /* maximum number of versions */
|
||||
union {
|
||||
unsigned char dir_b_flags;
|
||||
#define dir$b_flags dir__b_flags.dir_b_flags
|
||||
struct {
|
||||
unsigned char dir_v_type: DIR$S_TYPE;
|
||||
#define dir$v_type dir__b_flags.dir___b_flags.dir_v_type
|
||||
unsigned char: 3;
|
||||
unsigned char dir_v_nextrec: 1;
|
||||
#define dir$v_nextrec dir__b_flags.dir___b_flags.dir_v_nextrec
|
||||
unsigned char dir_v_prevrec: 1;
|
||||
#define dir$v_prevrec dir__b_flags.dir___b_flags.dir_v_prevrec
|
||||
} dir___b_flags;
|
||||
} dir__b_flags;
|
||||
unsigned char dir$b_namecount;
|
||||
char dir$t_name[];
|
||||
} dir$_dirdef; /* only the fixed first part */
|
||||
|
||||
typedef struct dir$_version {
|
||||
short dir$w_version;
|
||||
short dir$w_fid_num;
|
||||
short dir$w_fid_seq;
|
||||
union {
|
||||
short dir_w_fid_rvn;
|
||||
#define dir$w_fid_rvn dir__w_fid_rvn.dir_w_fid_rvn
|
||||
struct {
|
||||
char dir_b_fid_rvn;
|
||||
#define dir$b_fid_rvn dir__w_fid_rvn.dir___w_fid_rvn.dir_b_fid_rvn
|
||||
char dir_b_fid_nmx;
|
||||
#define dir$b_fid_nmx dir__w_fid_rvn.dir___w_fid_rvn.dir_b_fid_nmx
|
||||
} dir___w_fid_rvn;
|
||||
} dir__w_fid_rvn;
|
||||
} dir$_dirdef1; /* one for each version of the file */
|
||||
|
||||
typedef
|
||||
struct dir$_linkname {
|
||||
char dir$t_linkname[];
|
||||
} dir$_dirdef2;
|
||||
|
||||
#endif
|
14
src/vmsfns.c
14
src/vmsfns.c
@ -310,7 +310,7 @@ DEFUN ("spawn-subprocess", Fspawn_subprocess, Sspawn_subprocess, 1, 3, 0,
|
||||
prev->next = next;
|
||||
else
|
||||
process_list = next;
|
||||
if (! NULL (ptr->exit_handler))
|
||||
if (! NILP (ptr->exit_handler))
|
||||
Feval (Fcons (ptr->exit_handler, Fcons (make_number (ptr->name),
|
||||
Qnil)));
|
||||
sys$dassgn (ptr->mbx_chan);
|
||||
@ -327,7 +327,7 @@ DEFUN ("spawn-subprocess", Fspawn_subprocess, Sspawn_subprocess, 1, 3, 0,
|
||||
free (ptr);
|
||||
return Qnil;
|
||||
}
|
||||
if (NULL (input_handler))
|
||||
if (NILP (input_handler))
|
||||
input_handler = Qdefault_subproc_input_handler;
|
||||
ptr->input_handler = input_handler;
|
||||
ptr->exit_handler = exit_handler;
|
||||
@ -447,7 +447,7 @@ process_command_input ()
|
||||
have_process_input = 0;
|
||||
start_mbx_input ();
|
||||
clear_waiting_for_input (); /* Otherwise Ctl-g will cause crash. JCB */
|
||||
if (! NULL (expr))
|
||||
if (! NILP (expr))
|
||||
Feval (expr);
|
||||
}
|
||||
|
||||
@ -471,7 +471,7 @@ process_exit ()
|
||||
prev->next = next;
|
||||
else
|
||||
process_list = next;
|
||||
if (! NULL (ptr->exit_handler))
|
||||
if (! NILP (ptr->exit_handler))
|
||||
Feval (Fcons (ptr->exit_handler, Fcons (make_number (ptr->name),
|
||||
Qnil)));
|
||||
sys$dassgn (ptr->mbx_chan);
|
||||
@ -605,9 +605,9 @@ or nil depending upon whether the privilege is already enabled.")
|
||||
}
|
||||
if (! found)
|
||||
error ("Unknown privilege name %s", XSTRING (priv)->data);
|
||||
if (NULL (getprv))
|
||||
if (NILP (getprv))
|
||||
{
|
||||
if (sys$setprv (NULL (value) ? 0 : 1, prvmask, 0, 0) == SS$_NORMAL)
|
||||
if (sys$setprv (NILP (value) ? 0 : 1, prvmask, 0, 0) == SS$_NORMAL)
|
||||
return Qt;
|
||||
return Qnil;
|
||||
}
|
||||
@ -679,7 +679,7 @@ translate_id (pid, owner)
|
||||
char * p;
|
||||
int prcnam[2];
|
||||
|
||||
if (NULL (pid)
|
||||
if (NILP (pid)
|
||||
|| XTYPE (pid) == Lisp_String && XSTRING (pid)->size == 0
|
||||
|| XTYPE (pid) == Lisp_Int && XFASTINT (pid) == 0)
|
||||
{
|
||||
|
224
src/vmsmap.c
Normal file
224
src/vmsmap.c
Normal file
@ -0,0 +1,224 @@
|
||||
/* VMS mapping of data and alloc arena for GNU Emacs.
|
||||
Copyright (C) 1986, 1987 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Emacs is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Emacs; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Written by Mukesh Prasad. */
|
||||
|
||||
#ifdef VMS
|
||||
|
||||
#include "config.h"
|
||||
#include "lisp.h"
|
||||
#include <rab.h>
|
||||
#include <fab.h>
|
||||
#include <rmsdef.h>
|
||||
#include <secdef.h>
|
||||
|
||||
/* RMS block size */
|
||||
#define BLOCKSIZE 512
|
||||
|
||||
/* Maximum number of bytes to be written in one RMS write.
|
||||
* Must be a multiple of BLOCKSIZE.
|
||||
*/
|
||||
#define MAXWRITE (BLOCKSIZE * 30)
|
||||
|
||||
/* This funniness is to ensure that sdata occurs alphabetically BEFORE the
|
||||
$DATA psect and that edata occurs after ALL Emacs psects. This is
|
||||
because the VMS linker sorts all psects in a cluster alphabetically
|
||||
during the linking, unless you use the cluster_psect command. Emacs
|
||||
uses the cluster command to group all Emacs psects into one cluster;
|
||||
this keeps the dumped data separate from any loaded libraries. */
|
||||
|
||||
globaldef {"$D$ATA"} char sdata[512]; /* Start of saved data area */
|
||||
globaldef {"__DATA"} char edata[512]; /* End of saved data area */
|
||||
|
||||
/* Structure to write into first block of map file.
|
||||
*/
|
||||
|
||||
struct map_data
|
||||
{
|
||||
char * sdata; /* Start of data area */
|
||||
char * edata; /* End of data area */
|
||||
int datablk; /* Block in file to map data area from/to */
|
||||
};
|
||||
|
||||
static void fill_fab (), fill_rab ();
|
||||
static int write_data ();
|
||||
|
||||
extern char *start_of_data ();
|
||||
extern int vms_out_initial; /* Defined in malloc.c */
|
||||
|
||||
/* Maps in the data and alloc area from the map file.
|
||||
*/
|
||||
|
||||
int
|
||||
mapin_data (name)
|
||||
char * name;
|
||||
{
|
||||
struct FAB fab;
|
||||
struct RAB rab;
|
||||
int status, size;
|
||||
int inadr[2];
|
||||
struct map_data map_data;
|
||||
|
||||
/* Open map file. */
|
||||
fab = cc$rms_fab;
|
||||
fab.fab$b_fac = FAB$M_BIO|FAB$M_GET;
|
||||
fab.fab$l_fna = name;
|
||||
fab.fab$b_fns = strlen (name);
|
||||
status = sys$open (&fab);
|
||||
if (status != RMS$_NORMAL)
|
||||
{
|
||||
printf ("Map file not available, running bare Emacs....\n");
|
||||
return 0; /* Map file not available */
|
||||
}
|
||||
/* Connect the RAB block */
|
||||
rab = cc$rms_rab;
|
||||
rab.rab$l_fab = &fab;
|
||||
rab.rab$b_rac = RAB$C_SEQ;
|
||||
rab.rab$l_rop = RAB$M_BIO;
|
||||
status = sys$connect (&rab);
|
||||
if (status != RMS$_NORMAL)
|
||||
lib$stop (status);
|
||||
/* Read the header data */
|
||||
rab.rab$l_ubf = &map_data;
|
||||
rab.rab$w_usz = sizeof (map_data);
|
||||
rab.rab$l_bkt = 0;
|
||||
status = sys$read (&rab);
|
||||
if (status != RMS$_NORMAL)
|
||||
lib$stop (status);
|
||||
status = sys$close (&fab);
|
||||
if (status != RMS$_NORMAL)
|
||||
lib$stop (status);
|
||||
if (map_data.sdata != start_of_data ())
|
||||
{
|
||||
printf ("Start of data area has moved: cannot map in data.\n");
|
||||
return 0;
|
||||
}
|
||||
if (map_data.edata != edata)
|
||||
{
|
||||
printf ("End of data area has moved: cannot map in data.\n");
|
||||
return 0;
|
||||
}
|
||||
fab.fab$l_fop |= FAB$M_UFO;
|
||||
status = sys$open (&fab);
|
||||
if (status != RMS$_NORMAL)
|
||||
lib$stop (status);
|
||||
/* Map data area. */
|
||||
inadr[0] = map_data.sdata;
|
||||
inadr[1] = map_data.edata;
|
||||
status = sys$crmpsc (inadr, 0, 0, SEC$M_CRF | SEC$M_WRT, 0, 0, 0,
|
||||
fab.fab$l_stv, 0, map_data.datablk, 0, 0);
|
||||
if (! (status & 1))
|
||||
lib$stop (status);
|
||||
}
|
||||
|
||||
/* Writes the data and alloc area to the map file.
|
||||
*/
|
||||
mapout_data (into)
|
||||
char * into;
|
||||
{
|
||||
struct FAB fab;
|
||||
struct RAB rab;
|
||||
int status;
|
||||
struct map_data map_data;
|
||||
int datasize, msize;
|
||||
|
||||
if (vms_out_initial)
|
||||
{
|
||||
error ("Out of initial allocation. Must rebuild emacs with more memory (VMS_ALLOCATION_SIZE).");
|
||||
return 0;
|
||||
}
|
||||
map_data.sdata = start_of_data ();
|
||||
map_data.edata = edata;
|
||||
datasize = map_data.edata - map_data.sdata + 1;
|
||||
map_data.datablk = 2 + (sizeof (map_data) + BLOCKSIZE - 1) / BLOCKSIZE;
|
||||
/* Create map file. */
|
||||
fab = cc$rms_fab;
|
||||
fab.fab$b_fac = FAB$M_BIO|FAB$M_PUT;
|
||||
fab.fab$l_fna = into;
|
||||
fab.fab$b_fns = strlen (into);
|
||||
fab.fab$l_fop = FAB$M_CBT;
|
||||
fab.fab$b_org = FAB$C_SEQ;
|
||||
fab.fab$b_rat = 0;
|
||||
fab.fab$b_rfm = FAB$C_VAR;
|
||||
fab.fab$l_alq = 1 + map_data.datablk +
|
||||
((datasize + BLOCKSIZE - 1) / BLOCKSIZE);
|
||||
status = sys$create (&fab);
|
||||
if (status != RMS$_NORMAL)
|
||||
{
|
||||
error ("Could not create map file");
|
||||
return 0;
|
||||
}
|
||||
/* Connect the RAB block */
|
||||
rab = cc$rms_rab;
|
||||
rab.rab$l_fab = &fab;
|
||||
rab.rab$b_rac = RAB$C_SEQ;
|
||||
rab.rab$l_rop = RAB$M_BIO;
|
||||
status = sys$connect (&rab);
|
||||
if (status != RMS$_NORMAL)
|
||||
{
|
||||
error ("RMS connect to map file failed");
|
||||
return 0;
|
||||
}
|
||||
/* Write the header */
|
||||
rab.rab$l_rbf = &map_data;
|
||||
rab.rab$w_rsz = sizeof (map_data);
|
||||
status = sys$write (&rab);
|
||||
if (status != RMS$_NORMAL)
|
||||
{
|
||||
error ("RMS write (header) to map file failed");
|
||||
return 0;
|
||||
}
|
||||
if (! write_data (&rab, map_data.datablk, map_data.sdata, datasize))
|
||||
return 0;
|
||||
status = sys$close (&fab);
|
||||
if (status != RMS$_NORMAL)
|
||||
{
|
||||
error ("RMS close on map file failed");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
write_data (rab, firstblock, data, length)
|
||||
struct RAB * rab;
|
||||
char * data;
|
||||
{
|
||||
int status;
|
||||
|
||||
rab->rab$l_bkt = firstblock;
|
||||
while (length > 0)
|
||||
{
|
||||
rab->rab$l_rbf = data;
|
||||
rab->rab$w_rsz = length > MAXWRITE ? MAXWRITE : length;
|
||||
status = sys$write (rab, 0, 0);
|
||||
if (status != RMS$_NORMAL)
|
||||
{
|
||||
error ("RMS write to map file failed");
|
||||
return 0;
|
||||
}
|
||||
data = &data[MAXWRITE];
|
||||
length -= MAXWRITE;
|
||||
rab->rab$l_bkt = 0;
|
||||
}
|
||||
return 1;
|
||||
} /* write_data */
|
||||
|
||||
#endif /* VMS */
|
||||
|
15
src/vmspaths.h
Normal file
15
src/vmspaths.h
Normal file
@ -0,0 +1,15 @@
|
||||
/* the default search path for Lisp function "load" */
|
||||
#define PATH_LOADSEARCH "EMACS_LIBRARY:[LISP]"
|
||||
|
||||
/* the extra search path for programs to invoke.
|
||||
This is appended to whatever the PATH environment variable says. */
|
||||
#define PATH_EXEC "EMACS_LIBRARY:[ETC]"
|
||||
|
||||
/* the name of the directory that contains lock files
|
||||
with which we record what files are being modified in Emacs.
|
||||
This directory should be writable by everyone. */
|
||||
#define PATH_LOCK "EMACS_LIBRARY:[LOCK]"
|
||||
|
||||
/* the name of the file !!!SuperLock!!! in the directory
|
||||
specified by PATH_LOCK. Yes, this is redundant. */
|
||||
#define PATH_SUPERLOCK "EMACS_LIBRARY:[LOCK]$$$SUPERLOCK$$$."
|
@ -437,7 +437,7 @@ if you quit, the process is killed.")
|
||||
|
||||
CHECK_STRING (args[0], 0);
|
||||
|
||||
if (nargs <= 1 || NULL (args[1]))
|
||||
if (nargs <= 1 || NILP (args[1]))
|
||||
args[1] = build_string ("NLA0:");
|
||||
else
|
||||
args[1] = Fexpand_file_name (args[1], current_buffer->directory);
|
||||
@ -589,12 +589,12 @@ if you quit, the process is killed.")
|
||||
if (vs->iosb[0] & 1)
|
||||
{
|
||||
immediate_quit = 0;
|
||||
if (!NULL (buffer))
|
||||
if (!NILP (buffer))
|
||||
{
|
||||
vs->iosb[1] = clean_vms_buffer (vs->inputBuffer, vs->iosb[1]);
|
||||
InsCStr (vs->inputBuffer, vs->iosb[1]);
|
||||
}
|
||||
if (!NULL (display) && INTERACTIVE)
|
||||
if (!NILP (display) && INTERACTIVE)
|
||||
redisplay_preserve_echo_area ();
|
||||
immediate_quit = 1;
|
||||
QUIT;
|
||||
|
21
src/vmsproc.h
Normal file
21
src/vmsproc.h
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
Structure for storing VMS specific information for an EMACS process
|
||||
|
||||
We use the event flags 1-23 for processes, keyboard input and timer
|
||||
*/
|
||||
|
||||
/*
|
||||
Same as MAXDESC in process.c
|
||||
*/
|
||||
#define MAX_EVENT_FLAGS 23
|
||||
|
||||
typedef struct {
|
||||
char inputBuffer[1024];
|
||||
short inputChan;
|
||||
short outputChan;
|
||||
short busy;
|
||||
int pid;
|
||||
int eventFlag;
|
||||
int exitStatus;
|
||||
short iosb[4];
|
||||
} VMS_PROC_STUFF;
|
123
src/xscrollbar.h
Normal file
123
src/xscrollbar.h
Normal file
@ -0,0 +1,123 @@
|
||||
/* Bitmaps and things for scrollbars.
|
||||
Copyright (C) 1989 Free Software Foundation.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Emacs is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Emacs; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
|
||||
static void install_vertical_scrollbar ();
|
||||
static void install_horizontal_scrollbar ();
|
||||
static void x_set_horizontal_scrollbar ();
|
||||
static void x_set_vertical_scrollbar ();
|
||||
|
||||
/* Prefix-characters for scroll bar commands in Vglobal_mouse_map.
|
||||
Choice of prefix depends on which region of the scroll bar. */
|
||||
|
||||
enum scroll_bar_prefix
|
||||
{ VSCROLL_BAR_PREFIX = 050, VSCROLL_SLIDER_PREFIX /* unused */,
|
||||
VSCROLL_THUMBUP_PREFIX, VSCROLL_THUMBDOWN_PREFIX,
|
||||
HSCROLL_BAR_PREFIX, HSCROLL_SLIDER_PREFIX /* unused */,
|
||||
HSCROLL_THUMBLEFT_PREFIX, HSCROLL_THUMBRIGHT_PREFIX };
|
||||
|
||||
#define CROSS_WIDTH 16
|
||||
#define CROSS_HEIGHT 16
|
||||
|
||||
#define CROSS_MASK_WIDTH 16
|
||||
#define CROSS_MASK_HEIGHT 16
|
||||
|
||||
/* Vertical and Horizontal scroll bar widths. */
|
||||
#define VSCROLL_WIDTH 18
|
||||
#define HSCROLL_HEIGHT 18
|
||||
|
||||
#ifdef HAVE_X11
|
||||
|
||||
/* Arrow cursors for scroll bars. */
|
||||
|
||||
Cursor up_arrow_cursor, down_arrow_cursor, v_double_arrow_cursor;
|
||||
Cursor left_arrow_cursor, right_arrow_cursor, h_double_arrow_cursor;
|
||||
|
||||
static char cross_bits[] =
|
||||
{
|
||||
0x00, 0x00, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
|
||||
0x80, 0x01, 0xfe, 0x7f, 0xfe, 0x7f, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
|
||||
0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x00, 0x00
|
||||
};
|
||||
|
||||
static char gray_bits[] =
|
||||
{
|
||||
0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
|
||||
0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
|
||||
0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
|
||||
0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa
|
||||
};
|
||||
|
||||
static char up_arrow_bits[] =
|
||||
{
|
||||
0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f, 0xf8, 0x1f,
|
||||
0xfc, 0x3f, 0xfe, 0x7f, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
|
||||
0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xff, 0xff
|
||||
};
|
||||
|
||||
static char down_arrow_bits[] =
|
||||
{
|
||||
0xff, 0xff, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
|
||||
0x80, 0x01, 0x80, 0x01, 0xfe, 0x7f, 0xfc, 0x3f, 0xf8, 0x1f, 0xf0, 0x0f,
|
||||
0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00
|
||||
};
|
||||
|
||||
static char left_arrow_bits[] =
|
||||
{
|
||||
0x00, 0x80, 0x80, 0x80, 0xc0, 0x80, 0xe0, 0x80, 0xf0, 0x80, 0xf8, 0x80,
|
||||
0xfc, 0x80, 0xfe, 0xff, 0xfe, 0xff, 0xfc, 0x80, 0xf8, 0x80, 0xf0, 0x80,
|
||||
0xe0, 0x80, 0xc0, 0x80, 0x80, 0x80, 0x00, 0x80
|
||||
};
|
||||
|
||||
static char right_arrow_bits[] =
|
||||
{
|
||||
0x01, 0x00, 0x01, 0x01, 0x01, 0x03, 0x01, 0x07, 0x01, 0x0f, 0x01, 0x1f,
|
||||
0x01, 0x3f, 0xff, 0x7f, 0xff, 0x7f, 0x01, 0x3f, 0x01, 0x1f, 0x01, 0x0f,
|
||||
0x01, 0x07, 0x01, 0x03, 0x01, 0x01, 0x01, 0x00
|
||||
};
|
||||
|
||||
static char cross_mask_bits[] =
|
||||
{
|
||||
0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x03, 0xc0, 0x03,
|
||||
0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03
|
||||
};
|
||||
#else /* not HAVE_X11 */
|
||||
static short cross_bits[] =
|
||||
{
|
||||
0x0000, 0x0180, 0x0180, 0x0180,
|
||||
0x0180, 0x0180, 0x0180, 0x7ffe,
|
||||
0x7ffe, 0x0180, 0x0180, 0x0180,
|
||||
0x0180, 0x0180, 0x0180, 0x0000,
|
||||
};
|
||||
|
||||
static short gray_bits[] = {
|
||||
0xaaaa, 0x5555, 0xaaaa, 0x5555,
|
||||
0xaaaa, 0x5555, 0xaaaa, 0x5555,
|
||||
0xaaaa, 0x5555, 0xaaaa, 0x5555,
|
||||
0xaaaa, 0x5555, 0xaaaa, 0x5555};
|
||||
|
||||
static short cross_mask_bits[] =
|
||||
{
|
||||
0x03c0, 0x03c0, 0x03c0, 0x03c0,
|
||||
0x03c0, 0x03c0, 0xffff, 0xffff,
|
||||
0xffff, 0xffff, 0x03c0, 0x03c0,
|
||||
0x03c0, 0x03c0, 0x03c0, 0x03c0,
|
||||
};
|
||||
#endif /* X10 */
|
Loading…
Reference in New Issue
Block a user