| File: | src/usr.bin/vi/build/../ex/ex_args.c |
| Warning: | line 259, column 8 Although the value stored to 'len' is used in the enclosing expression, the value is never actually read from 'len' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* $OpenBSD: ex_args.c,v 1.12 2016/01/06 22:28:52 millert Exp $ */ |
| 2 | |
| 3 | /*- |
| 4 | * Copyright (c) 1991, 1993, 1994 |
| 5 | * The Regents of the University of California. All rights reserved. |
| 6 | * Copyright (c) 1991, 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/time.h> |
| 17 | |
| 18 | #include <bitstring.h> |
| 19 | #include <errno(*__errno()).h> |
| 20 | #include <limits.h> |
| 21 | #include <stdio.h> |
| 22 | #include <stdlib.h> |
| 23 | #include <string.h> |
| 24 | |
| 25 | #include "../common/common.h" |
| 26 | #include "../vi/vi.h" |
| 27 | |
| 28 | static int ex_N_next(SCR *, EXCMD *); |
| 29 | |
| 30 | /* |
| 31 | * ex_next -- :next [+cmd] [files] |
| 32 | * Edit the next file, optionally setting the list of files. |
| 33 | * |
| 34 | * !!! |
| 35 | * The :next command behaved differently from the :rewind command in |
| 36 | * historic vi. See nvi/docs/autowrite for details, but the basic |
| 37 | * idea was that it ignored the force flag if the autowrite flag was |
| 38 | * set. This implementation handles them all identically. |
| 39 | * |
| 40 | * PUBLIC: int ex_next(SCR *, EXCMD *); |
| 41 | */ |
| 42 | int |
| 43 | ex_next(SCR *sp, EXCMD *cmdp) |
| 44 | { |
| 45 | ARGS **argv; |
| 46 | FREF *frp; |
| 47 | int noargs; |
| 48 | char **ap; |
| 49 | |
| 50 | /* Check for file to move to. */ |
| 51 | if (cmdp->argc == 0 && (sp->cargv == NULL((void *)0) || sp->cargv[1] == NULL((void *)0))) { |
| 52 | msgq(sp, M_ERR, "No more files to edit"); |
| 53 | return (1); |
| 54 | } |
| 55 | |
| 56 | if (F_ISSET(cmdp, E_NEWSCREEN)(((cmdp)->flags) & ((0x00000100)))) { |
| 57 | /* By default, edit the next file in the old argument list. */ |
| 58 | if (cmdp->argc == 0) { |
| 59 | if (argv_exp0(sp, |
| 60 | cmdp, sp->cargv[1], strlen(sp->cargv[1]))) |
| 61 | return (1); |
| 62 | return (ex_edit(sp, cmdp)); |
| 63 | } |
| 64 | return (ex_N_next(sp, cmdp)); |
| 65 | } |
| 66 | |
| 67 | /* Check modification. */ |
| 68 | if (file_m1(sp, |
| 69 | FL_ISSET(cmdp->iflags, E_C_FORCE)((cmdp->iflags) & (0x00100)), FS_ALL0x001 | FS_POSSIBLE0x010)) |
| 70 | return (1); |
| 71 | |
| 72 | /* Any arguments are a replacement file list. */ |
| 73 | if (cmdp->argc) { |
| 74 | /* Free the current list. */ |
| 75 | if (!F_ISSET(sp, SC_ARGNOFREE)(((sp)->flags) & ((0x00002000))) && sp->argv != NULL((void *)0)) { |
| 76 | for (ap = sp->argv; *ap != NULL((void *)0); ++ap) |
| 77 | free(*ap); |
| 78 | free(sp->argv); |
| 79 | } |
| 80 | F_CLR(sp, SC_ARGNOFREE | SC_ARGRECOVER)(((sp)->flags) &= ~((0x00002000 | 0x00004000))); |
| 81 | sp->cargv = NULL((void *)0); |
| 82 | |
| 83 | /* Create a new list. */ |
| 84 | CALLOC_RET(sp,{ if (((sp->argv) = calloc((cmdp->argc + 1), (sizeof(char *)))) == ((void *)0)) { msgq((sp), M_SYSERR, ((void *)0)); return (1); } } |
| 85 | sp->argv, cmdp->argc + 1, sizeof(char *)){ if (((sp->argv) = calloc((cmdp->argc + 1), (sizeof(char *)))) == ((void *)0)) { msgq((sp), M_SYSERR, ((void *)0)); return (1); } }; |
| 86 | for (ap = sp->argv, |
| 87 | argv = cmdp->argv; argv[0]->len != 0; ++ap, ++argv) |
| 88 | if ((*ap = |
| 89 | v_strdup(sp, argv[0]->bp, argv[0]->len)) == NULL((void *)0)) |
| 90 | return (1); |
| 91 | *ap = NULL((void *)0); |
| 92 | |
| 93 | /* Switch to the first file. */ |
| 94 | sp->cargv = sp->argv; |
| 95 | if ((frp = file_add(sp, *sp->cargv)) == NULL((void *)0)) |
| 96 | return (1); |
| 97 | noargs = 0; |
| 98 | |
| 99 | /* Display a file count with the welcome message. */ |
| 100 | F_SET(sp, SC_STATUS_CNT)(((sp)->flags) |= ((0x04000000))); |
| 101 | } else { |
| 102 | if ((frp = file_add(sp, sp->cargv[1])) == NULL((void *)0)) |
| 103 | return (1); |
| 104 | if (F_ISSET(sp, SC_ARGRECOVER)(((sp)->flags) & ((0x00004000)))) |
| 105 | F_SET(frp, FR_RECOVER)(((frp)->flags) |= ((0x0020))); |
| 106 | noargs = 1; |
| 107 | } |
| 108 | |
| 109 | if (file_init(sp, frp, NULL((void *)0), FS_SETALT0x020 | |
| 110 | (FL_ISSET(cmdp->iflags, E_C_FORCE)((cmdp->iflags) & (0x00100)) ? FS_FORCE0x004 : 0))) |
| 111 | return (1); |
| 112 | if (noargs) |
| 113 | ++sp->cargv; |
| 114 | |
| 115 | F_SET(sp, SC_FSWITCH)(((sp)->flags) |= ((0x00000800))); |
| 116 | return (0); |
| 117 | } |
| 118 | |
| 119 | /* |
| 120 | * ex_N_next -- |
| 121 | * New screen version of ex_next. |
| 122 | */ |
| 123 | static int |
| 124 | ex_N_next(SCR *sp, EXCMD *cmdp) |
| 125 | { |
| 126 | SCR *new; |
| 127 | FREF *frp; |
| 128 | |
| 129 | /* Get a new screen. */ |
| 130 | if (screen_init(sp->gp, sp, &new)) |
| 131 | return (1); |
| 132 | if (vs_split(sp, new, 0)) { |
| 133 | (void)screen_end(new); |
| 134 | return (1); |
| 135 | } |
| 136 | |
| 137 | /* Get a backing file. */ |
| 138 | if ((frp = file_add(new, cmdp->argv[0]->bp)) == NULL((void *)0) || |
| 139 | file_init(new, frp, NULL((void *)0), |
| 140 | (FL_ISSET(cmdp->iflags, E_C_FORCE)((cmdp->iflags) & (0x00100)) ? FS_FORCE0x004 : 0))) { |
| 141 | (void)vs_discard(new, NULL((void *)0)); |
| 142 | (void)screen_end(new); |
| 143 | return (1); |
| 144 | } |
| 145 | |
| 146 | /* The arguments are a replacement file list. */ |
| 147 | new->cargv = new->argv = ex_buildargv(sp, cmdp, NULL((void *)0)); |
| 148 | |
| 149 | /* Display a file count with the welcome message. */ |
| 150 | F_SET(new, SC_STATUS_CNT)(((new)->flags) |= ((0x04000000))); |
| 151 | |
| 152 | /* Set up the switch. */ |
| 153 | sp->nextdisp = new; |
| 154 | F_SET(sp, SC_SSWITCH)(((sp)->flags) |= ((0x00001000))); |
| 155 | |
| 156 | return (0); |
| 157 | } |
| 158 | |
| 159 | /* |
| 160 | * ex_prev -- :prev |
| 161 | * Edit the previous file. |
| 162 | * |
| 163 | * PUBLIC: int ex_prev(SCR *, EXCMD *); |
| 164 | */ |
| 165 | int |
| 166 | ex_prev(SCR *sp, EXCMD *cmdp) |
| 167 | { |
| 168 | FREF *frp; |
| 169 | |
| 170 | if (sp->cargv == sp->argv) { |
| 171 | msgq(sp, M_ERR, "No previous files to edit"); |
| 172 | return (1); |
| 173 | } |
| 174 | |
| 175 | if (F_ISSET(cmdp, E_NEWSCREEN)(((cmdp)->flags) & ((0x00000100)))) { |
| 176 | if (argv_exp0(sp, cmdp, sp->cargv[-1], strlen(sp->cargv[-1]))) |
| 177 | return (1); |
| 178 | return (ex_edit(sp, cmdp)); |
| 179 | } |
| 180 | |
| 181 | if (file_m1(sp, |
| 182 | FL_ISSET(cmdp->iflags, E_C_FORCE)((cmdp->iflags) & (0x00100)), FS_ALL0x001 | FS_POSSIBLE0x010)) |
| 183 | return (1); |
| 184 | |
| 185 | if ((frp = file_add(sp, sp->cargv[-1])) == NULL((void *)0)) |
| 186 | return (1); |
| 187 | |
| 188 | if (file_init(sp, frp, NULL((void *)0), FS_SETALT0x020 | |
| 189 | (FL_ISSET(cmdp->iflags, E_C_FORCE)((cmdp->iflags) & (0x00100)) ? FS_FORCE0x004 : 0))) |
| 190 | return (1); |
| 191 | --sp->cargv; |
| 192 | |
| 193 | F_SET(sp, SC_FSWITCH)(((sp)->flags) |= ((0x00000800))); |
| 194 | return (0); |
| 195 | } |
| 196 | |
| 197 | /* |
| 198 | * ex_rew -- :rew |
| 199 | * Re-edit the list of files. |
| 200 | * |
| 201 | * !!! |
| 202 | * Historic practice was that all files would start editing at the beginning |
| 203 | * of the file. We don't get this right because we may have multiple screens |
| 204 | * and we can't clear the FR_CURSORSET bit for a single screen. I don't see |
| 205 | * anyone noticing, but if they do, we'll have to put information into the SCR |
| 206 | * structure so we can keep track of it. |
| 207 | * |
| 208 | * PUBLIC: int ex_rew(SCR *, EXCMD *); |
| 209 | */ |
| 210 | int |
| 211 | ex_rew(SCR *sp, EXCMD *cmdp) |
| 212 | { |
| 213 | FREF *frp; |
| 214 | |
| 215 | /* |
| 216 | * !!! |
| 217 | * Historic practice -- you can rewind to the current file. |
| 218 | */ |
| 219 | if (sp->argv == NULL((void *)0)) { |
| 220 | msgq(sp, M_ERR, "No previous files to rewind"); |
| 221 | return (1); |
| 222 | } |
| 223 | |
| 224 | if (file_m1(sp, |
| 225 | FL_ISSET(cmdp->iflags, E_C_FORCE)((cmdp->iflags) & (0x00100)), FS_ALL0x001 | FS_POSSIBLE0x010)) |
| 226 | return (1); |
| 227 | |
| 228 | /* Switch to the first one. */ |
| 229 | sp->cargv = sp->argv; |
| 230 | if ((frp = file_add(sp, *sp->cargv)) == NULL((void *)0)) |
| 231 | return (1); |
| 232 | if (file_init(sp, frp, NULL((void *)0), FS_SETALT0x020 | |
| 233 | (FL_ISSET(cmdp->iflags, E_C_FORCE)((cmdp->iflags) & (0x00100)) ? FS_FORCE0x004 : 0))) |
| 234 | return (1); |
| 235 | |
| 236 | /* Switch and display a file count with the welcome message. */ |
| 237 | F_SET(sp, SC_FSWITCH | SC_STATUS_CNT)(((sp)->flags) |= ((0x00000800 | 0x04000000))); |
| 238 | |
| 239 | return (0); |
| 240 | } |
| 241 | |
| 242 | /* |
| 243 | * ex_args -- :args |
| 244 | * Display the list of files. |
| 245 | * |
| 246 | * PUBLIC: int ex_args(SCR *, EXCMD *); |
| 247 | */ |
| 248 | int |
| 249 | ex_args(SCR *sp, EXCMD *cmdp) |
| 250 | { |
| 251 | int cnt, col, len, sep; |
| 252 | char **ap; |
| 253 | |
| 254 | if (sp->argv == NULL((void *)0)) { |
| 255 | (void)msgq(sp, M_ERR, "No file list to display"); |
| 256 | return (0); |
| 257 | } |
| 258 | |
| 259 | col = len = sep = 0; |
Although the value stored to 'len' is used in the enclosing expression, the value is never actually read from 'len' | |
| 260 | for (cnt = 1, ap = sp->argv; *ap != NULL((void *)0); ++ap) { |
| 261 | col += len = strlen(*ap) + sep + (ap == sp->cargv ? 2 : 0); |
| 262 | if (col >= sp->cols - 1) { |
| 263 | col = len; |
| 264 | sep = 0; |
| 265 | (void)ex_puts(sp, "\n"); |
| 266 | } else if (cnt != 1) { |
| 267 | sep = 1; |
| 268 | (void)ex_puts(sp, " "); |
| 269 | } |
| 270 | ++cnt; |
| 271 | |
| 272 | (void)ex_printf(sp, "%s%s%s", ap == sp->cargv ? "[" : "", |
| 273 | *ap, ap == sp->cargv ? "]" : ""); |
| 274 | if (INTERRUPTED(sp)(((((sp)->gp)->flags) & ((0x0004))) || (!v_event_get ((sp), ((void *)0), 0, 0x001) && ((((sp)->gp)-> flags) & ((0x0004)))))) |
| 275 | break; |
| 276 | } |
| 277 | (void)ex_puts(sp, "\n"); |
| 278 | return (0); |
| 279 | } |
| 280 | |
| 281 | /* |
| 282 | * ex_buildargv -- |
| 283 | * Build a new file argument list. |
| 284 | * |
| 285 | * PUBLIC: char **ex_buildargv(SCR *, EXCMD *, char *); |
| 286 | */ |
| 287 | char ** |
| 288 | ex_buildargv(SCR *sp, EXCMD *cmdp, char *name) |
| 289 | { |
| 290 | ARGS **argv; |
| 291 | int argc; |
| 292 | char **ap, **s_argv; |
| 293 | |
| 294 | argc = cmdp == NULL((void *)0) ? 1 : cmdp->argc; |
| 295 | CALLOC(sp, s_argv, argc + 1, sizeof(char *)){ if (((s_argv) = calloc((argc + 1), (sizeof(char *)))) == (( void *)0)) msgq((sp), M_SYSERR, ((void *)0)); }; |
| 296 | if ((ap = s_argv) == NULL((void *)0)) |
| 297 | return (NULL((void *)0)); |
| 298 | |
| 299 | if (cmdp == NULL((void *)0)) { |
| 300 | if ((*ap = v_strdup(sp, name, strlen(name))) == NULL((void *)0)) { |
| 301 | free(s_argv); |
| 302 | return (NULL((void *)0)); |
| 303 | } |
| 304 | ++ap; |
| 305 | } else |
| 306 | for (argv = cmdp->argv; argv[0]->len != 0; ++ap, ++argv) |
| 307 | if ((*ap = |
| 308 | v_strdup(sp, argv[0]->bp, argv[0]->len)) == NULL((void *)0)) { |
| 309 | while (--ap >= s_argv) |
| 310 | free(*ap); |
| 311 | free(s_argv); |
| 312 | return (NULL((void *)0)); |
| 313 | } |
| 314 | *ap = NULL((void *)0); |
| 315 | return (s_argv); |
| 316 | } |