1 /* $NetBSD: ex_edit.c,v 1.7 2014/01/26 21:43:45 christos Exp $ */ 2 /*- 3 * Copyright (c) 1992, 1993, 1994 4 * The Regents of the University of California. All rights reserved. 5 * Copyright (c) 1992, 1993, 1994, 1995, 1996 6 * Keith Bostic. All rights reserved. 7 * 8 * See the LICENSE file for redistribution information. 9 */ 10 11 #include "config.h" 12 13 #include <sys/cdefs.h> 14 #if 0 15 #ifndef lint 16 static const char sccsid[] = "Id: ex_edit.c,v 10.14 2001/08/28 13:29:15 skimo Exp (Berkeley) Date: 2001/08/28 13:29:15 "; 17 #endif /* not lint */ 18 #else 19 __RCSID("$NetBSD: ex_edit.c,v 1.7 2014/01/26 21:43:45 christos Exp $"); 20 #endif 21 22 #include <sys/types.h> 23 #include <sys/queue.h> 24 #include <sys/time.h> 25 26 #include <bitstring.h> 27 #include <errno.h> 28 #include <limits.h> 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <string.h> 32 33 #include "../common/common.h" 34 #include "../vi/vi.h" 35 36 static int ex_N_edit __P((SCR *, EXCMD *, FREF *, int)); 37 38 /* 39 * ex_edit -- :e[dit][!] [+cmd] [file] 40 * :ex[!] [+cmd] [file] 41 * :vi[sual][!] [+cmd] [file] 42 * 43 * Edit a file; if none specified, re-edit the current file. The third 44 * form of the command can only be executed while in vi mode. See the 45 * hack in ex.c:ex_cmd(). 46 * 47 * !!! 48 * Historic vi didn't permit the '+' command form without specifying 49 * a file name as well. This seems unreasonable, so we support it 50 * regardless. 51 * 52 * PUBLIC: int ex_edit __P((SCR *, EXCMD *)); 53 */ 54 int 55 ex_edit(SCR *sp, EXCMD *cmdp) 56 { 57 FREF *frp; 58 int attach, setalt; 59 const char *np; 60 size_t nlen; 61 62 switch (cmdp->argc) { 63 case 0: 64 /* 65 * If the name has been changed, we edit that file, not the 66 * original name. If the user was editing a temporary file 67 * (or wasn't editing any file), create another one. The 68 * reason for not reusing temporary files is that there is 69 * special exit processing of them, and reuse is tricky. 70 */ 71 frp = sp->frp; 72 if (sp->ep == NULL || F_ISSET(frp, FR_TMPFILE)) { 73 if ((frp = file_add(sp, NULL)) == NULL) 74 return (1); 75 attach = 0; 76 } else 77 attach = 1; 78 setalt = 0; 79 break; 80 case 1: 81 INT2CHAR(sp, cmdp->argv[0]->bp, cmdp->argv[0]->len + 1, 82 np, nlen); 83 if ((frp = file_add(sp, np)) == NULL) 84 return (1); 85 attach = 0; 86 setalt = 1; 87 set_alt_name(sp, np); 88 break; 89 default: 90 abort(); 91 } 92 93 if (F_ISSET(cmdp, E_NEWSCREEN) || cmdp->cmd == &cmds[C_VSPLIT]) 94 return (ex_N_edit(sp, cmdp, frp, attach)); 95 96 /* 97 * Check for modifications. 98 * 99 * !!! 100 * Contrary to POSIX 1003.2-1992, autowrite did not affect :edit. 101 */ 102 if (file_m2(sp, FL_ISSET(cmdp->iflags, E_C_FORCE))) 103 return (1); 104 105 /* Switch files. */ 106 if (file_init(sp, frp, NULL, (setalt ? FS_SETALT : 0) | 107 (FL_ISSET(cmdp->iflags, E_C_FORCE) ? FS_FORCE : 0))) 108 return (1); 109 110 F_SET(sp, SC_FSWITCH); 111 return (0); 112 } 113 114 /* 115 * ex_N_edit -- 116 * New screen version of ex_edit. 117 */ 118 static int 119 ex_N_edit(SCR *sp, EXCMD *cmdp, FREF *frp, int attach) 120 { 121 SCR *new; 122 123 /* Get a new screen. */ 124 if (screen_init(sp->gp, sp, &new)) 125 return (1); 126 if ((cmdp->cmd == &cmds[C_VSPLIT] && vs_vsplit(sp, new)) || 127 (cmdp->cmd != &cmds[C_VSPLIT] && vs_split(sp, new, 0))) { 128 (void)screen_fini(new); 129 return (1); 130 } 131 132 /* Get a backing file. */ 133 if (attach) { 134 /* Copy file state, keep the screen and cursor the same. */ 135 new->ep = sp->ep; 136 ++new->ep->refcnt; 137 TAILQ_INSERT_HEAD(&new->ep->scrq, new, eq); 138 139 new->frp = frp; 140 new->frp->flags = sp->frp->flags; 141 142 new->lno = sp->lno; 143 new->cno = sp->cno; 144 } else if (file_init(new, frp, NULL, 145 (FL_ISSET(cmdp->iflags, E_C_FORCE) ? FS_FORCE : 0))) { 146 (void)vs_discard(new, NULL); 147 (void)screen_end(new); 148 return (1); 149 } 150 151 /* Create the argument list. */ 152 new->cargv = new->argv = ex_buildargv(sp, NULL, frp->name); 153 154 /* Set up the switch. */ 155 sp->nextdisp = new; 156 F_SET(sp, SC_SSWITCH); 157 158 return (0); 159 } 160