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