1 | /* $NetBSD: ed.h,v 1.38 2019/01/04 19:13:58 maya Exp $ */ |
2 | |
3 | /* ed.h: type and constant definitions for the ed editor. */ |
4 | /* |
5 | * Copyright (c) 1993 Andrew Moore |
6 | * All rights reserved. |
7 | * |
8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions |
10 | * are met: |
11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. |
13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the |
15 | * documentation and/or other materials provided with the distribution. |
16 | * |
17 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
27 | * SUCH DAMAGE. |
28 | * |
29 | * @(#)ed.h,v 1.5 1994/02/01 00:34:39 alm Exp |
30 | */ |
31 | #include <sys/types.h> |
32 | #if defined(BSD) && BSD >= 199103 || defined(__386BSD__) |
33 | # include <sys/param.h> /* for MAXPATHLEN */ |
34 | #endif |
35 | #include <errno.h> |
36 | #if defined(sun) || defined(__NetBSD__) || defined(__APPLE__) |
37 | # include <limits.h> |
38 | #endif |
39 | #include <regex.h> |
40 | #include <signal.h> |
41 | #include <stdio.h> |
42 | #include <stdlib.h> |
43 | #include <string.h> |
44 | #include <unistd.h> |
45 | |
46 | #define ERR (-2) |
47 | #define EMOD (-3) |
48 | #define FATAL (-4) |
49 | |
50 | #ifndef MAXPATHLEN |
51 | # define MAXPATHLEN 255 /* _POSIX_PATH_MAX */ |
52 | #endif |
53 | |
54 | #define MINBUFSZ 512 /* minimum buffer size - must be > 0 */ |
55 | #define SE_MAX 30 /* max subexpressions in a regular expression */ |
56 | #ifdef INT_MAX |
57 | # define LINECHARS INT_MAX /* max chars per line */ |
58 | #else |
59 | # define LINECHARS MAXINT /* max chars per line */ |
60 | #endif |
61 | |
62 | /* gflags */ |
63 | #define GLB 001 /* global command */ |
64 | #define GPR 002 /* print after command */ |
65 | #define GLS 004 /* list after command */ |
66 | #define GNP 010 /* enumerate after command */ |
67 | #define GSG 020 /* global substitute */ |
68 | |
69 | typedef regex_t pattern_t; |
70 | |
71 | /* Line node */ |
72 | typedef struct line { |
73 | struct line *q_forw; |
74 | struct line *q_back; |
75 | off_t seek; /* address of line in scratch buffer */ |
76 | int len; /* length of line */ |
77 | } line_t; |
78 | |
79 | |
80 | typedef struct undo { |
81 | |
82 | /* type of undo nodes */ |
83 | #define UADD 0 |
84 | #define UDEL 1 |
85 | #define UMOV 2 |
86 | #define VMOV 3 |
87 | |
88 | int type; /* command type */ |
89 | line_t *h; /* head of list */ |
90 | line_t *t; /* tail of list */ |
91 | } undo_t; |
92 | |
93 | #ifndef max |
94 | # define max(a,b) ((a) > (b) ? (a) : (b)) |
95 | #endif |
96 | #ifndef min |
97 | # define min(a,b) ((a) < (b) ? (a) : (b)) |
98 | #endif |
99 | |
100 | #define INC_MOD(l, k) ((l) + 1 > (k) ? 0 : (l) + 1) |
101 | #define DEC_MOD(l, k) ((l) - 1 < 0 ? (k) : (l) - 1) |
102 | |
103 | /* SPL1: disable some interrupts (requires reliable signals) */ |
104 | #define SPL1() mutex++ |
105 | |
106 | /* SPL0: enable all interrupts; check sigflags (requires reliable signals) */ |
107 | #define SPL0() \ |
108 | if (--mutex == 0) { \ |
109 | if (sigflags & (1 << (SIGHUP - 1))) handle_hup(SIGHUP); \ |
110 | if (sigflags & (1 << (SIGINT - 1))) handle_int(SIGINT); \ |
111 | } |
112 | |
113 | /* STRTOL: convert a string to long */ |
114 | #define STRTOL(i, p) { \ |
115 | errno = 0 ; \ |
116 | if (((i = strtol(p, &p, 10)) == LONG_MIN || i == LONG_MAX) && \ |
117 | errno == ERANGE) { \ |
118 | seterrmsg("number out of range"); \ |
119 | i = 0; \ |
120 | return ERR; \ |
121 | } \ |
122 | } |
123 | |
124 | /* REALLOC: assure at least a minimum size for buffer b */ |
125 | #define REALLOC(b,n,i,err) \ |
126 | if ((i) > (n)) { \ |
127 | int ti = (n); \ |
128 | char *ts; \ |
129 | SPL1(); \ |
130 | if ((ts = (char *) realloc((b), ti += max((i), MINBUFSZ))) == NULL) { \ |
131 | fprintf(stderr, "%s\n", strerror(errno)); \ |
132 | seterrmsg("out of memory"); \ |
133 | SPL0(); \ |
134 | return err; \ |
135 | } \ |
136 | (n) = ti; \ |
137 | (b) = ts; \ |
138 | SPL0(); \ |
139 | } |
140 | |
141 | /* REQUE: link pred before succ */ |
142 | #define REQUE(pred, succ) (pred)->q_forw = (succ), (succ)->q_back = (pred) |
143 | |
144 | /* INSQUE: insert elem in circular queue after pred */ |
145 | #define INSQUE(elem, pred) \ |
146 | { \ |
147 | REQUE((elem), (pred)->q_forw); \ |
148 | REQUE((pred), elem); \ |
149 | } |
150 | |
151 | /* remque: remove_lines elem from circular queue */ |
152 | #define REMQUE(elem) REQUE((elem)->q_back, (elem)->q_forw); |
153 | |
154 | /* NUL_TO_NEWLINE: overwrite ASCII NULs with newlines */ |
155 | #define NUL_TO_NEWLINE(s, l) translit_text(s, l, '\0', '\n') |
156 | |
157 | /* NEWLINE_TO_NUL: overwrite newlines with ASCII NULs */ |
158 | #define NEWLINE_TO_NUL(s, l) translit_text(s, l, '\n', '\0') |
159 | |
160 | #if defined(sun) && !defined(__SVR4) |
161 | # define strerror(n) sys_errlist[n] |
162 | #endif |
163 | |
164 | /* Local Function Declarations */ |
165 | void add_line_node(line_t *); |
166 | int append_lines(long); |
167 | int apply_subst_template(char *, regmatch_t *, int, int); |
168 | int build_active_list(int); |
169 | int check_addr_range(long, long); |
170 | void clear_active_list(void); |
171 | void clear_undo_stack(void); |
172 | int close_sbuf(void); |
173 | int copy_lines(long); |
174 | int delete_lines(long, long); |
175 | int display_lines(long, long, int); |
176 | line_t *dup_line_node(line_t *); |
177 | int exec_command(void); |
178 | long exec_global(int, int); |
179 | int (void); |
180 | char *(int); |
181 | int (int *, long *); |
182 | char *(void); |
183 | int filter_lines(long, long, char *); |
184 | int flush_des_file(FILE *); |
185 | line_t *get_addressed_line_node(long); |
186 | pattern_t *get_compiled_pattern(void); |
187 | int get_des_char(FILE *); |
188 | char *get_extended_line(int *, int); |
189 | char *get_filename(void); |
190 | int get_keyword(void); |
191 | long get_line_node_addr(line_t *); |
192 | long get_matching_node_addr(pattern_t *, int); |
193 | long get_marked_node_addr(int); |
194 | char *get_sbuf_line(line_t *); |
195 | int get_shell_command(void); |
196 | int get_stream_line(FILE *); |
197 | int get_tty_line(void); |
198 | __dead void handle_hup(int); |
199 | __dead void handle_int(int); |
200 | void handle_winch(int); |
201 | int has_trailing_escape(char *, char *); |
202 | void init_buffers(void); |
203 | void init_des_cipher(void); |
204 | int is_legal_filename(char *); |
205 | int join_lines(long, long); |
206 | int mark_line_node(line_t *, int); |
207 | int move_lines(long); |
208 | line_t *next_active_node(void); |
209 | long next_addr(void); |
210 | int open_sbuf(void); |
211 | char *parse_char_class(char *); |
212 | int pop_undo_stack(void); |
213 | undo_t *push_undo_stack(int, long, long); |
214 | int put_des_char(int, FILE *); |
215 | char *put_sbuf_line(char *); |
216 | int put_stream_line(FILE *, char *, int); |
217 | int put_tty_line(char *, int, long, int); |
218 | __dead void quit(int); |
219 | long read_file(char *, long); |
220 | long read_stream(FILE *, long); |
221 | int search_and_replace(pattern_t *, int, int); |
222 | int set_active_node(line_t *); |
223 | void signal_hup(int); |
224 | void signal_int(int); |
225 | char *strip_escapes(const char *); |
226 | int substitute_matching_text(pattern_t *, line_t *, int, int); |
227 | char *translit_text(char *, int, int, int); |
228 | void unmark_line_node(line_t *); |
229 | void unset_active_nodes(line_t *, line_t *); |
230 | long write_file(const char *, const char *, long, long); |
231 | long write_stream(FILE *, long, long); |
232 | void seterrmsg(const char *, ...) __printflike(1, 2); |
233 | |
234 | /* global buffers */ |
235 | extern char stdinbuf[]; |
236 | extern char *ibuf; |
237 | extern char *ibufp; |
238 | extern int ibufsz; |
239 | |
240 | /* global flags */ |
241 | extern int isbinary; |
242 | extern int isglobal; |
243 | extern int modified; |
244 | extern int mutex; |
245 | extern int sigflags; |
246 | |
247 | /* global vars */ |
248 | extern long addr_last; |
249 | extern long current_addr; |
250 | extern long first_addr; |
251 | extern int lineno; |
252 | extern long second_addr; |
253 | extern long rows; |
254 | extern int cols; |
255 | extern int scripted; |
256 | extern int ere; |
257 | extern int des; |
258 | extern int newline_added; /* io.c */ |
259 | extern int patlock; |
260 | extern char errmsg[]; /* re.c */ |
261 | extern long u_current_addr; /* undo.c */ |
262 | extern long u_addr_last; /* undo.c */ |
263 | #if defined(sun) && !defined(__SVR4) |
264 | extern char *sys_errlist[]; |
265 | #endif |
266 | |