1 /*- 2 * Copyright (c) 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * Copyright (c) 1993, 1994, 1995, 1996 5 * Keith Bostic. All rights reserved. 6 * 7 * See the LICENSE file for redistribution information. 8 */ 9 10 #include "config.h" 11 12 #ifndef lint 13 static const char sccsid[] = "@(#)ex_util.c 10.23 (Berkeley) 6/19/96"; 14 #endif /* not lint */ 15 16 #include <sys/types.h> 17 #include <sys/queue.h> 18 #include <sys/stat.h> 19 20 #include <bitstring.h> 21 #include <errno.h> 22 #include <limits.h> 23 #include <stdio.h> 24 #include <stdlib.h> 25 #include <string.h> 26 #include <unistd.h> 27 28 #include "../common/common.h" 29 30 /* 31 * ex_cinit -- 32 * Create an EX command structure. 33 * 34 * PUBLIC: void ex_cinit __P((EXCMD *, 35 * PUBLIC: int, int, recno_t, recno_t, int, ARGS **)); 36 */ 37 void 38 ex_cinit(cmdp, cmd_id, naddr, lno1, lno2, force, ap) 39 EXCMD *cmdp; 40 int cmd_id, force, naddr; 41 recno_t lno1, lno2; 42 ARGS **ap; 43 { 44 memset(cmdp, 0, sizeof(EXCMD)); 45 cmdp->cmd = &cmds[cmd_id]; 46 cmdp->addrcnt = naddr; 47 cmdp->addr1.lno = lno1; 48 cmdp->addr2.lno = lno2; 49 cmdp->addr1.cno = cmdp->addr2.cno = 1; 50 if (force) 51 cmdp->iflags |= E_C_FORCE; 52 cmdp->argc = 0; 53 if ((cmdp->argv = ap) != NULL) 54 cmdp->argv[0] = NULL; 55 } 56 57 /* 58 * ex_cadd -- 59 * Add an argument to an EX command structure. 60 * 61 * PUBLIC: void ex_cadd __P((EXCMD *, ARGS *, char *, size_t)); 62 */ 63 void 64 ex_cadd(cmdp, ap, arg, len) 65 EXCMD *cmdp; 66 ARGS *ap; 67 char *arg; 68 size_t len; 69 { 70 cmdp->argv[cmdp->argc] = ap; 71 ap->bp = arg; 72 ap->len = len; 73 cmdp->argv[++cmdp->argc] = NULL; 74 } 75 76 /* 77 * ex_getline -- 78 * Return a line from the file. 79 * 80 * PUBLIC: int ex_getline __P((SCR *, FILE *, size_t *)); 81 */ 82 int 83 ex_getline(sp, fp, lenp) 84 SCR *sp; 85 FILE *fp; 86 size_t *lenp; 87 { 88 EX_PRIVATE *exp; 89 size_t off; 90 int ch; 91 char *p; 92 93 exp = EXP(sp); 94 for (errno = 0, off = 0, p = exp->ibp;;) { 95 if (off >= exp->ibp_len) { 96 BINC_RET(sp, exp->ibp, exp->ibp_len, off + 1); 97 p = exp->ibp + off; 98 } 99 if ((ch = getc(fp)) == EOF && !feof(fp)) { 100 if (errno == EINTR) { 101 errno = 0; 102 clearerr(fp); 103 continue; 104 } 105 return (1); 106 } 107 if (ch == EOF || ch == '\n') { 108 if (ch == EOF && !off) 109 return (1); 110 *lenp = off; 111 return (0); 112 } 113 *p++ = ch; 114 ++off; 115 } 116 /* NOTREACHED */ 117 } 118 119 /* 120 * ex_ncheck -- 121 * Check for more files to edit. 122 * 123 * PUBLIC: int ex_ncheck __P((SCR *, int)); 124 */ 125 int 126 ex_ncheck(sp, force) 127 SCR *sp; 128 int force; 129 { 130 char **ap; 131 132 /* 133 * !!! 134 * Historic practice: quit! or two quit's done in succession 135 * (where ZZ counts as a quit) didn't check for other files. 136 */ 137 if (!force && sp->ccnt != sp->q_ccnt + 1 && 138 sp->cargv != NULL && sp->cargv[1] != NULL) { 139 sp->q_ccnt = sp->ccnt; 140 141 for (ap = sp->cargv + 1; *ap != NULL; ++ap); 142 msgq(sp, M_ERR, 143 "167|%d more files to edit", (ap - sp->cargv) - 1); 144 145 return (1); 146 } 147 return (0); 148 } 149 150 /* 151 * ex_init -- 152 * Init the screen for ex. 153 * 154 * PUBLIC: int ex_init __P((SCR *)); 155 */ 156 int 157 ex_init(sp) 158 SCR *sp; 159 { 160 GS *gp; 161 162 gp = sp->gp; 163 164 if (gp->scr_screen(sp, SC_EX)) 165 return (1); 166 (void)gp->scr_attr(sp, SA_ALTERNATE, 0); 167 168 sp->rows = O_VAL(sp, O_LINES); 169 sp->cols = O_VAL(sp, O_COLUMNS); 170 171 F_CLR(sp, SC_VI); 172 F_SET(sp, SC_EX | SC_SCR_EX); 173 return (0); 174 } 175 176 /* 177 * ex_emsg -- 178 * Display a few common ex and vi error messages. 179 * 180 * PUBLIC: void ex_emsg __P((SCR *, char *, exm_t)); 181 */ 182 void 183 ex_emsg(sp, p, which) 184 SCR *sp; 185 char *p; 186 exm_t which; 187 { 188 switch (which) { 189 case EXM_EMPTYBUF: 190 msgq(sp, M_ERR, "168|Buffer %s is empty", p); 191 break; 192 case EXM_FILECOUNT: 193 msgq_str(sp, M_ERR, p, 194 "144|%s: expanded into too many file names"); 195 break; 196 case EXM_NOCANON: 197 msgq(sp, M_ERR, 198 "283|The %s command requires the ex terminal interface", p); 199 break; 200 case EXM_NOCANON_F: 201 msgq(sp, M_ERR, 202 "272|That form of %s requires the ex terminal interface", 203 p); 204 break; 205 case EXM_NOFILEYET: 206 if (p == NULL) 207 msgq(sp, M_ERR, 208 "274|Command failed, no file read in yet."); 209 else 210 msgq(sp, M_ERR, 211 "173|The %s command requires that a file have already been read in", p); 212 break; 213 case EXM_NOPREVBUF: 214 msgq(sp, M_ERR, "171|No previous buffer to execute"); 215 break; 216 case EXM_NOPREVRE: 217 msgq(sp, M_ERR, "172|No previous regular expression"); 218 break; 219 case EXM_NOSUSPEND: 220 msgq(sp, M_ERR, "230|This screen may not be suspended"); 221 break; 222 case EXM_SECURE: 223 msgq(sp, M_ERR, 224 "290|The %s command is not supported when the secure edit option is set", p); 225 break; 226 case EXM_SECURE_F: 227 msgq(sp, M_ERR, 228 "284|That form of %s is not supported when the secure edit option is set", p); 229 break; 230 case EXM_USAGE: 231 msgq(sp, M_ERR, "174|Usage: %s", p); 232 break; 233 } 234 } 235