xref: /original-bsd/contrib/ed/m.c (revision 06194916)
1 /*-
2  * Copyright (c) 1992, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Rodney Ruddock of the University of Guelph.
7  *
8  * %sccs.include.redist.c%
9  */
10 
11 #ifndef lint
12 static char sccsid[] = "@(#)m.c	8.1 (Berkeley) 05/31/93";
13 #endif /* not lint */
14 
15 #include <sys/types.h>
16 
17 #include <regex.h>
18 #include <setjmp.h>
19 #include <stdio.h>
20 #include <string.h>
21 
22 #ifdef DBI
23 #include <db.h>
24 #endif
25 
26 #include "ed.h"
27 #include "extern.h"
28 
29 /*
30  * Move the specified lines to the new location. It's quick 'cause
31  * just a couple of pointers are redirected.
32  */
33 void
34 m(inputt, errnum)
35 	FILE *inputt;
36 	int *errnum;
37 {
38 	LINE *l_dest=NULL, *l_old_top, *l_old_bottom;
39 
40 	/* Set l_dest here. */
41 	if (((ss = getc(inputt)) != '\n') && (ss != EOF)) {
42 		for (;;) {
43 			if (ss != ' ') {
44 				ungetc(ss, inputt);
45 				break;
46 			}
47 			ss = getc(inputt);
48 		}
49 		l_dest = address_conv(NULL, inputt, errnum);
50 	} else
51 		(ungetc(ss, inputt), *errnum = -1);
52 	if (*errnum < 0) {
53 		strcpy(help_msg, "bad destination address");
54 		return;
55 	}
56 	*errnum = 0;
57 	if (rol(inputt, errnum))
58 		return;
59 
60 	if (Start_default && End_default)
61 		Start = End = current;
62 	else
63 		if (Start_default)
64 			Start = End;
65 	if (Start == NULL) {
66 		strcpy(help_msg, "buffer empty");
67 		*errnum = -1;
68 		return;
69 	}
70 	Start_default = End_default = 0;
71 
72 	/* Do some address checking. */
73 	if ((l_dest) && ((l_dest == Start) ||
74 	    (address_check(l_dest, Start) == -1)) &&
75 	    (address_check(End, l_dest) == -1)) {
76 		ungetc(ss, inputt);
77 		*errnum = -1;
78 		strcpy(help_msg, "destination address in address range");
79 		return;
80 	}
81 	change_flag = 1;
82 	if (g_flag == 0)
83 		u_clr_stk();
84 
85 	/*
86 	 * Some more address checking. These are "legal" command constructions
87 	 * but are kind-a useless since the buffer doesn't change.
88 	 */
89 	*errnum = 1;
90 	if ((Start == l_dest) || (End == l_dest))
91 		return;
92 	if ((Start == top) && (End == bottom))
93 		return;
94 	if ((Start == top) && (l_dest == NULL))
95 		return;
96 	*errnum = 0;
97 
98 	l_old_top = top;
99 	l_old_bottom = bottom;
100 
101 	sigspecial++;
102 
103 	if (Start == top) {
104 		top = End->below;
105 		u_add_stk(&(End->below->above));
106 		top->above = NULL;
107 	} else
108 		if (End == bottom) {
109 			bottom = Start->above;
110 			u_add_stk(&(Start->above->below));
111 			bottom->below = NULL;
112 		} else {
113 			u_add_stk(&(Start->above->below));
114 			Start->above->below = End->below;
115 			u_add_stk(&(End->below->above));
116 			End->below->above = Start->above;
117 		}
118 
119 	if (l_dest == NULL) {
120 		u_add_stk(&(Start->above));
121 		Start->above = NULL;
122 		u_add_stk(&(End->below));
123 		End->below = l_old_top;
124 		u_add_stk(&(l_old_top->above));
125 		l_old_top->above = End;
126 		top = Start;
127 	} else
128 		if (l_dest == l_old_bottom) {
129 			u_add_stk(&(End->below));
130 			End->below = NULL;
131 			u_add_stk(&(Start->above));
132 			Start->above = l_dest;
133 			u_add_stk(&(l_dest->below));
134 			l_dest->below = Start;
135 			bottom = End;
136 		} else {
137 			u_add_stk(&(Start->above));
138 			Start->above = l_dest;
139 			u_add_stk(&(End->below));
140 			End->below = l_dest->below;
141 			u_add_stk(&(l_dest->below->above));
142 			l_dest->below->above = End;
143 			u_add_stk(&(l_dest->below));
144 			l_dest->below = Start;
145 		}
146 
147 	if (l_dest)
148 		l_dest->below = Start;
149 	current = Start;
150 
151 	sigspecial--;
152 
153 	*errnum = 1;
154 }
155