]>
diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/miscellany/less-177/edit.c
10 #define ISPIPE(fd) ((fd)==0)
14 extern int quit_at_eof
;
17 extern char *every_first_cmd
;
18 extern int any_display
;
19 extern int force_open
;
21 extern IFILE curr_ifile
;
22 extern IFILE old_ifile
;
23 extern struct scrpos initial_scrpos
;
27 extern int force_logfile
;
28 extern char *namelogfile
;
34 * Filename == "-" means standard input.
35 * Filename == NULL means just close the current file.
38 edit(filename
, just_looking
)
39 register char *filename
;
52 * Close the current file, but don't open a new one.
55 } else if (strcmp(filename
, "-") == 0)
61 } else if ((parg
.p_string
= bad_file(filename
)) != NULL
)
67 } else if ((f
= open(filename
, O_RDONLY
|O_BINARY
)) < 0)
69 } else if ((f
= open(filename
, 0)) < 0)
72 parg
.p_string
= errno_message(filename
);
76 } else if (!force_open
&& !just_looking
&& bin_file(f
))
78 parg
.p_string
= filename
;
79 answer
= query("\"%s\" may be a binary file. Continue? ",
81 if (answer
!= 'y' && answer
!= 'Y')
88 if (f
>= 0 && isatty(f
))
91 * Not really necessary to call this an error,
92 * but if the control terminal (for commands)
93 * and the input file (for data) are the same,
94 * we get weird results at best.
97 parg
.p_string
= "less -?";
99 parg
.p_string
= "less -\\?";
101 error("Cannot take input from a terminal (\"%s\" for help)",
111 if (f
>= 0 && ISPIPE(f
) && s
!= NULL
&& is_tty
)
116 * We are now committed to using the new file.
117 * Close the current input file and set up to use the new one.
119 if (curr_ifile
!= NULL_IFILE
)
122 * Save the current position so that we can return to
123 * the same position if we edit this file again.
126 if (scrpos
.pos
!= NULL_POSITION
)
128 store_pos(curr_ifile
, &scrpos
);
134 * Close the current file, unless it is a pipe.
145 * Get the saved position for that file.
147 old_ifile
= curr_ifile
;
148 curr_ifile
= get_ifile(filename
, curr_ifile
);
149 get_pos(curr_ifile
, &initial_scrpos
);
156 (void) ch_nbuf(cbufs
);
165 if (every_first_cmd
!= NULL
)
166 ungetsc(every_first_cmd
);
168 no_display
= !any_display
;
175 * Output is to a real tty.
179 * Indicate there is nothing displayed yet.
183 if (no_display
&& errmsgs
> 0)
186 * We displayed some messages on error output
187 * (file descriptor 2; see error() function).
188 * Before erasing the screen contents,
189 * display the file name and wait for a keystroke.
191 parg
.p_string
= filename
;
199 * Edit a space-separated list of files.
200 * For each filename in the list, enter it into the ifile list.
201 * Then edit the first one.
209 register char *filename
;
211 IFILE save_curr_ifile
;
214 * good_filename keeps track of the first valid filename.
216 good_filename
= NULL
;
219 save_curr_ifile
= curr_ifile
;
220 while ((s
= skipsp(s
)) < es
)
223 * Get the next filename and null terminate it.
226 while (*s
!= ' ' && *s
!= '\0')
231 * Try to edit the file.
232 * This enters it into the command line list (if it is good).
233 * If it is the first good file we've seen, remember it.
234 * {{ A little weirdness here: if any of the filenames
235 * are already in the list, subsequent ones get
236 * entered after the position where that one already
237 * was, instead of at the end. }}
239 if (edit(filename
, 1) == 0 && good_filename
== NULL
)
240 good_filename
= filename
;
244 * Edit the first valid filename in the list.
246 if (good_filename
!= NULL
)
248 curr_ifile
= save_curr_ifile
;
249 (void) edit(good_filename
, 0);
254 * Edit the first file in the command line (ifile) list.
259 curr_ifile
= NULL_IFILE
;
260 return (edit_next(1));
264 * Edit the last file in the command line (ifile) list.
269 curr_ifile
= NULL_IFILE
;
270 return (edit_prev(1));
275 * Edit the next file in the command line (ifile) list.
284 while (--n
>= 0 || edit(get_filename(h
), 0))
286 if ((h
= next_ifile(h
)) == NULL_IFILE
)
288 * Reached end of the ifile list.
293 * Found a file that we can edit.
299 * Edit the previous file in the command line list.
308 while (--n
>= 0 || edit(get_filename(h
), 0))
310 if ((h
= prev_ifile(h
)) == NULL_IFILE
)
312 * Reached beginning of the ifile list.
317 * Found a file that we can edit.
323 * Edit a specific file in the command line (ifile) list.
334 if ((h
= next_ifile(h
)) == NULL_IFILE
)
337 * Reached end of the list without finding it.
341 } while (get_index(h
) != n
);
343 return (edit(get_filename(h
), 0));
347 * Copy a file directly to standard output.
348 * Used if standard output is not a tty.
355 while ((c
= ch_forw_get()) != EOI
)
363 * If the user asked for a log file and our input file
364 * is standard input, create the log file.
365 * We take care not to blindly overwrite an existing file.
368 use_logfile(filename
)
376 * {{ We could use access() here. }}
378 exists
= open(filename
, 0);
380 exists
= (exists
>= 0);
383 * Decide whether to overwrite the log file or append to it.
384 * (If it doesn't exist we "overwrite" it.
386 if (!exists
|| force_logfile
)
389 * Overwrite (or create) the log file.
395 * Ask user what to do.
397 parg
.p_string
= filename
;
398 answer
= query("Warning: \"%s\" exists; Overwrite, Append or Don't log? ", &parg
);
406 * Overwrite: create the file.
408 logfile
= creat(filename
, 0644);
412 * Append: open the file and seek to the end.
415 logfile
= open(filename
, O_APPEND
|O_WRONLY
);
417 logfile
= open(filename
, 1);
419 if (lseek(logfile
, (offset_t
)0, 2) == BAD_LSEEK
)
437 answer
= query("Overwrite, Append, or Don't log? ", NULL_PARG
);
444 * Error in opening logfile.
446 parg
.p_string
= filename
;
447 error("Cannot write to \"%s\"", &parg
);