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