130154ac8SAndrew Moore /* ed.h: type and constant definitions for the ed editor. */ 29ddb49cbSWarner Losh /*- 395e6217eSAndrew Moore * Copyright (c) 1993 Andrew Moore 430154ac8SAndrew Moore * All rights reserved. 530154ac8SAndrew Moore * 630154ac8SAndrew Moore * Redistribution and use in source and binary forms, with or without 730154ac8SAndrew Moore * modification, are permitted provided that the following conditions 830154ac8SAndrew Moore * are met: 930154ac8SAndrew Moore * 1. Redistributions of source code must retain the above copyright 1030154ac8SAndrew Moore * notice, this list of conditions and the following disclaimer. 1130154ac8SAndrew Moore * 2. Redistributions in binary form must reproduce the above copyright 1230154ac8SAndrew Moore * notice, this list of conditions and the following disclaimer in the 1330154ac8SAndrew Moore * documentation and/or other materials provided with the distribution. 1430154ac8SAndrew Moore * 1530154ac8SAndrew Moore * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 1630154ac8SAndrew Moore * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1730154ac8SAndrew Moore * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1830154ac8SAndrew Moore * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 1930154ac8SAndrew Moore * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2030154ac8SAndrew Moore * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2130154ac8SAndrew Moore * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2230154ac8SAndrew Moore * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2330154ac8SAndrew Moore * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2430154ac8SAndrew Moore * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2530154ac8SAndrew Moore * SUCH DAMAGE. 2630154ac8SAndrew Moore */ 2730154ac8SAndrew Moore 289842e24cSWarner Losh #include <sys/param.h> 2995e6217eSAndrew Moore #include <errno.h> 3095e6217eSAndrew Moore #include <limits.h> 3130154ac8SAndrew Moore #include <regex.h> 3230154ac8SAndrew Moore #include <signal.h> 3395e6217eSAndrew Moore #include <stdio.h> 3495e6217eSAndrew Moore #include <stdlib.h> 3595e6217eSAndrew Moore #include <string.h> 3695e6217eSAndrew Moore #include <unistd.h> 3730154ac8SAndrew Moore 3830154ac8SAndrew Moore #define ERR (-2) 3930154ac8SAndrew Moore #define EMOD (-3) 4030154ac8SAndrew Moore #define FATAL (-4) 4130154ac8SAndrew Moore 4230154ac8SAndrew Moore #define MINBUFSZ 512 /* minimum buffer size - must be > 0 */ 4330154ac8SAndrew Moore #define SE_MAX 30 /* max subexpressions in a regular expression */ 4495e6217eSAndrew Moore #ifdef INT_MAX 4595e6217eSAndrew Moore # define LINECHARS INT_MAX /* max chars per line */ 4695e6217eSAndrew Moore #else 4795e6217eSAndrew Moore # define LINECHARS MAXINT /* max chars per line */ 4895e6217eSAndrew Moore #endif 4995e6217eSAndrew Moore 5095e6217eSAndrew Moore /* gflags */ 5195e6217eSAndrew Moore #define GLB 001 /* global command */ 5295e6217eSAndrew Moore #define GPR 002 /* print after command */ 5395e6217eSAndrew Moore #define GLS 004 /* list after command */ 5495e6217eSAndrew Moore #define GNP 010 /* enumerate after command */ 5595e6217eSAndrew Moore #define GSG 020 /* global substitute */ 5630154ac8SAndrew Moore 5730154ac8SAndrew Moore typedef regex_t pattern_t; 5830154ac8SAndrew Moore 5930154ac8SAndrew Moore /* Line node */ 6030154ac8SAndrew Moore typedef struct line { 6195e6217eSAndrew Moore struct line *q_forw; 6295e6217eSAndrew Moore struct line *q_back; 6330154ac8SAndrew Moore off_t seek; /* address of line in scratch buffer */ 6430154ac8SAndrew Moore int len; /* length of line */ 6530154ac8SAndrew Moore } line_t; 6630154ac8SAndrew Moore 6730154ac8SAndrew Moore 6830154ac8SAndrew Moore typedef struct undo { 6930154ac8SAndrew Moore 7030154ac8SAndrew Moore /* type of undo nodes */ 7130154ac8SAndrew Moore #define UADD 0 7230154ac8SAndrew Moore #define UDEL 1 7330154ac8SAndrew Moore #define UMOV 2 7430154ac8SAndrew Moore #define VMOV 3 7530154ac8SAndrew Moore 7630154ac8SAndrew Moore int type; /* command type */ 7730154ac8SAndrew Moore line_t *h; /* head of list */ 7830154ac8SAndrew Moore line_t *t; /* tail of list */ 7930154ac8SAndrew Moore } undo_t; 8030154ac8SAndrew Moore 8130154ac8SAndrew Moore #ifndef max 8230154ac8SAndrew Moore # define max(a,b) ((a) > (b) ? (a) : (b)) 8330154ac8SAndrew Moore #endif 8430154ac8SAndrew Moore #ifndef min 8530154ac8SAndrew Moore # define min(a,b) ((a) < (b) ? (a) : (b)) 8630154ac8SAndrew Moore #endif 8730154ac8SAndrew Moore 8895e6217eSAndrew Moore #define INC_MOD(l, k) ((l) + 1 > (k) ? 0 : (l) + 1) 8995e6217eSAndrew Moore #define DEC_MOD(l, k) ((l) - 1 < 0 ? (k) : (l) - 1) 9030154ac8SAndrew Moore 9195e6217eSAndrew Moore /* SPL1: disable some interrupts (requires reliable signals) */ 9295e6217eSAndrew Moore #define SPL1() mutex++ 9330154ac8SAndrew Moore 9495e6217eSAndrew Moore /* SPL0: enable all interrupts; check sigflags (requires reliable signals) */ 9595e6217eSAndrew Moore #define SPL0() \ 9630154ac8SAndrew Moore if (--mutex == 0) { \ 9795e6217eSAndrew Moore if (sigflags & (1 << (SIGHUP - 1))) handle_hup(SIGHUP); \ 9895e6217eSAndrew Moore if (sigflags & (1 << (SIGINT - 1))) handle_int(SIGINT); \ 9995e6217eSAndrew Moore } 10095e6217eSAndrew Moore 10195e6217eSAndrew Moore /* STRTOL: convert a string to long */ 10295e6217eSAndrew Moore #define STRTOL(i, p) { \ 10395e6217eSAndrew Moore if (((i = strtol(p, &p, 10)) == LONG_MIN || i == LONG_MAX) && \ 10495e6217eSAndrew Moore errno == ERANGE) { \ 105a4616748SMike Barcroft errmsg = "number out of range"; \ 10695e6217eSAndrew Moore i = 0; \ 10795e6217eSAndrew Moore return ERR; \ 10895e6217eSAndrew Moore } \ 10930154ac8SAndrew Moore } 11030154ac8SAndrew Moore 11130154ac8SAndrew Moore #if defined(sun) || defined(NO_REALLOC_NULL) 11295e6217eSAndrew Moore /* REALLOC: assure at least a minimum size for buffer b */ 11395e6217eSAndrew Moore #define REALLOC(b,n,i,err) \ 11430154ac8SAndrew Moore if ((i) > (n)) { \ 115*27150ef8SPedro F. Giffuni size_t ti = (n); \ 11630154ac8SAndrew Moore char *ts; \ 11795e6217eSAndrew Moore SPL1(); \ 11830154ac8SAndrew Moore if ((b) != NULL) { \ 11930154ac8SAndrew Moore if ((ts = (char *) realloc((b), ti += max((i), MINBUFSZ))) == NULL) { \ 12030154ac8SAndrew Moore fprintf(stderr, "%s\n", strerror(errno)); \ 121a4616748SMike Barcroft errmsg = "out of memory"; \ 12295e6217eSAndrew Moore SPL0(); \ 12330154ac8SAndrew Moore return err; \ 12430154ac8SAndrew Moore } \ 12530154ac8SAndrew Moore } else { \ 12630154ac8SAndrew Moore if ((ts = (char *) malloc(ti += max((i), MINBUFSZ))) == NULL) { \ 12730154ac8SAndrew Moore fprintf(stderr, "%s\n", strerror(errno)); \ 128a4616748SMike Barcroft errmsg = "out of memory"; \ 12995e6217eSAndrew Moore SPL0(); \ 13030154ac8SAndrew Moore return err; \ 13130154ac8SAndrew Moore } \ 13230154ac8SAndrew Moore } \ 13330154ac8SAndrew Moore (n) = ti; \ 13430154ac8SAndrew Moore (b) = ts; \ 13595e6217eSAndrew Moore SPL0(); \ 13630154ac8SAndrew Moore } 13730154ac8SAndrew Moore #else /* NO_REALLOC_NULL */ 13895e6217eSAndrew Moore /* REALLOC: assure at least a minimum size for buffer b */ 13995e6217eSAndrew Moore #define REALLOC(b,n,i,err) \ 14030154ac8SAndrew Moore if ((i) > (n)) { \ 141*27150ef8SPedro F. Giffuni size_t ti = (n); \ 14230154ac8SAndrew Moore char *ts; \ 14395e6217eSAndrew Moore SPL1(); \ 14430154ac8SAndrew Moore if ((ts = (char *) realloc((b), ti += max((i), MINBUFSZ))) == NULL) { \ 14530154ac8SAndrew Moore fprintf(stderr, "%s\n", strerror(errno)); \ 146a4616748SMike Barcroft errmsg = "out of memory"; \ 14795e6217eSAndrew Moore SPL0(); \ 14830154ac8SAndrew Moore return err; \ 14930154ac8SAndrew Moore } \ 15030154ac8SAndrew Moore (n) = ti; \ 15130154ac8SAndrew Moore (b) = ts; \ 15295e6217eSAndrew Moore SPL0(); \ 15330154ac8SAndrew Moore } 15430154ac8SAndrew Moore #endif /* NO_REALLOC_NULL */ 15530154ac8SAndrew Moore 15695e6217eSAndrew Moore /* REQUE: link pred before succ */ 15795e6217eSAndrew Moore #define REQUE(pred, succ) (pred)->q_forw = (succ), (succ)->q_back = (pred) 15830154ac8SAndrew Moore 159d165d4acSAndrew Moore /* INSQUE: insert elem in circular queue after pred */ 160d165d4acSAndrew Moore #define INSQUE(elem, pred) \ 16130154ac8SAndrew Moore { \ 16295e6217eSAndrew Moore REQUE((elem), (pred)->q_forw); \ 16395e6217eSAndrew Moore REQUE((pred), elem); \ 16430154ac8SAndrew Moore } 16530154ac8SAndrew Moore 166d165d4acSAndrew Moore /* REMQUE: remove_lines elem from circular queue */ 167d165d4acSAndrew Moore #define REMQUE(elem) REQUE((elem)->q_back, (elem)->q_forw); 16830154ac8SAndrew Moore 16995e6217eSAndrew Moore /* NUL_TO_NEWLINE: overwrite ASCII NULs with newlines */ 17095e6217eSAndrew Moore #define NUL_TO_NEWLINE(s, l) translit_text(s, l, '\0', '\n') 17130154ac8SAndrew Moore 17295e6217eSAndrew Moore /* NEWLINE_TO_NUL: overwrite newlines with ASCII NULs */ 17395e6217eSAndrew Moore #define NEWLINE_TO_NUL(s, l) translit_text(s, l, '\n', '\0') 17430154ac8SAndrew Moore 175eb338d36SMark Murray 17695e6217eSAndrew Moore /* Local Function Declarations */ 1777669d0fcSWarner Losh void add_line_node(line_t *); 1787669d0fcSWarner Losh int append_lines(long); 1797669d0fcSWarner Losh int apply_subst_template(const char *, regmatch_t *, int, int); 1807669d0fcSWarner Losh int build_active_list(int); 18113fcef50SMark Murray int cbc_decode(unsigned char *, FILE *); 18213fcef50SMark Murray int cbc_encode(unsigned char *, int, FILE *); 1837669d0fcSWarner Losh int check_addr_range(long, long); 1847669d0fcSWarner Losh void clear_active_list(void); 1857669d0fcSWarner Losh void clear_undo_stack(void); 1867669d0fcSWarner Losh int close_sbuf(void); 1877669d0fcSWarner Losh int copy_lines(long); 1887669d0fcSWarner Losh int delete_lines(long, long); 1897669d0fcSWarner Losh int display_lines(long, long, int); 1907669d0fcSWarner Losh line_t *dup_line_node(line_t *); 1917669d0fcSWarner Losh int exec_command(void); 1927669d0fcSWarner Losh long exec_global(int, int); 1937669d0fcSWarner Losh int extract_addr_range(void); 1947669d0fcSWarner Losh char *extract_pattern(int); 1957669d0fcSWarner Losh int extract_subst_tail(int *, long *); 1967669d0fcSWarner Losh char *extract_subst_template(void); 1977669d0fcSWarner Losh int filter_lines(long, long, char *); 1987669d0fcSWarner Losh line_t *get_addressed_line_node(long); 1997669d0fcSWarner Losh pattern_t *get_compiled_pattern(void); 2007669d0fcSWarner Losh char *get_extended_line(int *, int); 2017669d0fcSWarner Losh char *get_filename(void); 2027669d0fcSWarner Losh int get_keyword(void); 2037669d0fcSWarner Losh long get_line_node_addr(line_t *); 2047669d0fcSWarner Losh long get_matching_node_addr(pattern_t *, int); 2057669d0fcSWarner Losh long get_marked_node_addr(int); 2067669d0fcSWarner Losh char *get_sbuf_line(line_t *); 2077669d0fcSWarner Losh int get_shell_command(void); 2087669d0fcSWarner Losh int get_stream_line(FILE *); 2097669d0fcSWarner Losh int get_tty_line(void); 2107669d0fcSWarner Losh void handle_hup(int); 2117669d0fcSWarner Losh void handle_int(int); 2127669d0fcSWarner Losh void handle_winch(int); 2137669d0fcSWarner Losh int has_trailing_escape(char *, char *); 2147669d0fcSWarner Losh int hex_to_binary(int, int); 2157669d0fcSWarner Losh void init_buffers(void); 2167669d0fcSWarner Losh int is_legal_filename(char *); 2177669d0fcSWarner Losh int join_lines(long, long); 2187669d0fcSWarner Losh int mark_line_node(line_t *, int); 2197669d0fcSWarner Losh int move_lines(long); 2207669d0fcSWarner Losh line_t *next_active_node(void); 2217669d0fcSWarner Losh long next_addr(void); 2227669d0fcSWarner Losh int open_sbuf(void); 2237669d0fcSWarner Losh char *parse_char_class(char *); 2247669d0fcSWarner Losh int pop_undo_stack(void); 2257669d0fcSWarner Losh undo_t *push_undo_stack(int, long, long); 2267669d0fcSWarner Losh const char *put_sbuf_line(const char *); 2277669d0fcSWarner Losh int put_stream_line(FILE *, const char *, int); 2287669d0fcSWarner Losh int put_tty_line(const char *, int, long, int); 2297669d0fcSWarner Losh void quit(int); 2307669d0fcSWarner Losh long read_file(char *, long); 2317669d0fcSWarner Losh long read_stream(FILE *, long); 2327669d0fcSWarner Losh int search_and_replace(pattern_t *, int, int); 2337669d0fcSWarner Losh int set_active_node(line_t *); 2347669d0fcSWarner Losh void signal_hup(int); 2357669d0fcSWarner Losh void signal_int(int); 2367669d0fcSWarner Losh char *strip_escapes(char *); 2377669d0fcSWarner Losh int substitute_matching_text(pattern_t *, line_t *, int, int); 2387669d0fcSWarner Losh char *translit_text(char *, int, int, int); 2397669d0fcSWarner Losh void unmark_line_node(line_t *); 2407669d0fcSWarner Losh void unset_active_nodes(line_t *, line_t *); 2417669d0fcSWarner Losh long write_file(char *, const char *, long, long); 2427669d0fcSWarner Losh long write_stream(FILE *, long, long); 24330154ac8SAndrew Moore 24495e6217eSAndrew Moore /* global buffers */ 24595e6217eSAndrew Moore extern char stdinbuf[]; 24695e6217eSAndrew Moore extern char *ibuf; 24795e6217eSAndrew Moore extern char *ibufp; 24895e6217eSAndrew Moore extern int ibufsz; 24930154ac8SAndrew Moore 25095e6217eSAndrew Moore /* global flags */ 25195e6217eSAndrew Moore extern int isbinary; 25295e6217eSAndrew Moore extern int isglobal; 25395e6217eSAndrew Moore extern int modified; 25430154ac8SAndrew Moore extern int mutex; 25530154ac8SAndrew Moore extern int sigflags; 25695e6217eSAndrew Moore 25795e6217eSAndrew Moore /* global vars */ 25895e6217eSAndrew Moore extern long addr_last; 25995e6217eSAndrew Moore extern long current_addr; 260a4616748SMike Barcroft extern const char *errmsg; 26195e6217eSAndrew Moore extern long first_addr; 26295e6217eSAndrew Moore extern int lineno; 26395e6217eSAndrew Moore extern long second_addr; 2640e6c085aSJuli Mallett extern long u_addr_last; 2650e6c085aSJuli Mallett extern long u_current_addr; 266bf70beceSEd Schouten extern long rows; 267bf70beceSEd Schouten extern int cols; 268bf70beceSEd Schouten extern int newline_added; 269bf70beceSEd Schouten extern int scripted; 270bf70beceSEd Schouten extern int patlock; 271