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