xref: /original-bsd/contrib/ed/j.c (revision ac773626)
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[] = "@(#)j.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 <stdlib.h>
21 #include <string.h>
22 
23 #ifdef DBI
24 #include <db.h>
25 #endif
26 
27 #include "ed.h"
28 #include "extern.h"
29 
30 /*
31  * Join the spec'd lines onto one line. Make the new line from the
32  * old lines and then delete the old ones (undo-able).
33  */
34 
35 void
36 j(inputt, errnum)
37 	FILE *inputt;
38 	int *errnum;
39 {
40 	LINE *l_ptr, *l_temp_line;
41 	long l_ttl = 0;
42 	char *l_temp1;
43 
44 	if (Start_default && End_default) {
45 		Start = current;
46 		*errnum = 1;
47 		if (Start == NULL) {
48 			strcpy(help_msg, "buffer empty");
49 			*errnum = -1;
50 			return;
51 		} else
52 			if ((Start->below) != NULL)
53 				End = Start->below;
54 		else
55 			return;
56 	} else
57 		if (Start_default) {
58 			if (rol(inputt, errnum))
59 				return;
60 
61 			if (End == NULL) {
62 				strcpy(help_msg, "bad address");
63 				*errnum = -1;
64 			} else {
65 #ifdef BSD
66 				/*
67 				 * For BSD a 'j' with one address sets
68 				 * "current" to that line
69 				 */
70 				if (Start)
71 					current = Start;
72 #endif
73 				*errnum = 1;
74 			}
75 			return;
76 		}
77 
78 	if (Start == NULL) {
79 		strcpy(help_msg, "buffer empty");
80 		*errnum = -1;
81 		return;
82 	}
83 
84 	Start_default = End_default = 0;
85 
86 	if (rol(inputt, errnum))
87 		return;
88 
89 	if (g_flag == 0)
90 		u_clr_stk();
91 	u_set = 1;		/* set for d */
92 
93 	/* Figure out what the length of the joined lines will be. */
94 	for (l_ptr = Start; l_ptr != (End->below); l_ptr = (l_ptr->below))
95 		l_ttl = l_ptr->len + l_ttl;
96 
97 	if (l_ttl > nn_max) {
98 		/*
99 		 * The new line is bigger than any so far, so make more
100 		 * space.
101 		 */
102 		sigspecial++;
103 		free(text);
104 		nn_max = l_ttl;
105 		text = calloc(l_ttl + 2, sizeof(char));
106 		sigspecial--;
107 		if (text == NULL) {
108 			*errnum = -1;
109 			strcpy(help_msg, "out of memory error");
110 			return;
111 		}
112 	}
113 	l_temp1 = calloc(l_ttl + 2, sizeof(char));
114 	if (l_temp1 == NULL) {
115 		*errnum = -1;
116 		strcpy(help_msg, "out of memory error");
117 		return;
118 	}
119 	l_temp1[0] = '\0';
120 
121 	l_ptr = Start;
122 
123 	sigspecial++;
124 	for (;;) {
125 		/* Get each line and catenate. */
126 		get_line(l_ptr->handle, l_ptr->len);
127 		if (sigint_flag && (!sigspecial))
128 			goto point;
129 		strcat(l_temp1, text);
130 		l_ptr = l_ptr->below;
131 		if (l_ptr == End->below)
132 			break;
133 	}
134 
135 	l_temp_line = malloc(sizeof(LINE));
136 	if (l_temp_line == NULL) {
137 		*errnum = -1;
138 		strcpy(help_msg, "out of memory error");
139 		return;
140 	}
141 	(l_temp_line->len) = l_ttl;
142 	/* Add the new line to the buffer. */
143 	(l_temp_line->handle) = add_line(l_temp1, l_ttl);
144 	if (Start == top) {
145 		top = l_temp_line;
146 		(l_temp_line->above) = NULL;
147 	} else {
148 		(l_temp_line->above) = Start->above;
149 		u_add_stk(&(l_temp_line->above->below));
150 		(l_temp_line->above->below) = l_temp_line;
151 	}
152 	(l_temp_line->below) = Start;
153 	u_add_stk(&(Start->above));
154 	(Start->above) = l_temp_line;
155 
156 	sigspecial--;
157 	if (sigint_flag && (!sigspecial))
158 		goto mk;
159 	ungetc(ss, inputt);
160 	/* Delete the lines used to make the joined line. */
161 	join_flag = 1;
162 	d(inputt, errnum);
163 	join_flag = 0;
164 	if (*errnum < 0)
165 		return;
166 	*errnum = 0;
167 mk:
168 	current = l_temp_line;
169 
170 	*errnum = 1;
171 
172 point:	u_set = 0;
173 	free(l_temp1);
174 }
175