* Copyright (c) 1992 Diomidis Spinellis.
* Copyright (c) 1992 The Regents of the University of California.
* This code is derived from software contributed to Berkeley by
* Diomidis Spinellis of Imperial College, University of London.
* %sccs.include.redist.c%
"@(#) Copyright (c) 1992 The Regents of the University of California.\n\
static char sccsid
[] = "@(#)main.c 5.4 (Berkeley) %G%";
* Linked list of units (strings and files) to be compiled
enum e_cut
{CU_FILE
, CU_STRING
} type
;
char *s
; /* Pointer to string or fname */
* Linked list pointer to compilation units and pointer to current
static struct s_compunit
*script
, **cu_nextp
= &script
;
* Linked list of files to be processed
* Linked list pointer to files and pointer to current
static struct s_flist
*files
, **fl_nextp
= &files
;
* Current file and line number; line numbers restart across compilation
* units, but span across input files.
char *fname
; /* File name. */
int lastline
; /* TRUE on the last line of the last file */
static void add_compunit
__P((enum e_cut
, char *));
static void add_file
__P((char *));
while ((c
= getopt(argc
, argv
, "ae:f:n")) != EOF
)
add_compunit(CU_STRING
, optarg
);
add_compunit(CU_FILE
, optarg
);
"usage:\tsed script [-an] [file ...]\n\tsed [-an] [-e script] ... [-f scipt_file] ... [file ...]\n");
/* First usage case; script is the first arg */
if (!eflag
&& !fflag
&& *argv
) {
add_compunit(CU_STRING
, *argv
);
/* Continue with first and start second usage */
err(FATAL
, "stdout: %s", strerror(errno
));
* Like fgets, but go through the chain of compilation units chaining them
* together. Empty strings and files are ignored.
static enum {ST_EOF
, ST_FILE
, ST_STRING
} state
= ST_EOF
;
static FILE *f
; /* Current open file */
static char *s
; /* Current pointer inside string */
static char string_ident
[30];
if ((f
= fopen(script
->s
, "r")) == NULL
)
"%s: %s", script
->s
, strerror(errno
));
if ((snprintf(string_ident
,
sizeof(string_ident
), "\"%s\"", script
->s
)) >=
sizeof(string_ident
) - 1)
(void)strcpy(string_ident
+
sizeof(string_ident
) - 6, " ...\"");
if ((p
= fgets(buf
, n
, f
)) != NULL
) {
if (linenum
== 1 && buf
[0] == '#' && buf
[1] == 'n')
if (linenum
== 0 && s
[0] == '#' && s
[1] == 'n')
* Like fgets, but go through the list of files chaining them together.
* Set len to the length of the line.
static FILE *f
; /* Current open file */
/* Advance to first non-empty file */
if (files
->fname
== NULL
) {
if ((f
= fopen(fname
, "r")) == NULL
)
if ((c
= getc(f
)) != EOF
) {
err(FATAL
, "%s: %s", fname
, strerror(errno
? errno
: EIO
));
/* Advance to next non-empty file */
while ((c
= getc(f
)) == EOF
) {
if (files
->fname
== NULL
) {
if ((f
= fopen(fname
, "r")) == NULL
)
err(FATAL
, "%s: %s", fname
, strerror(errno
));
* Add a compilation unit to the linked list
cu
= xmalloc(sizeof(struct s_compunit
));
* Add a file to the linked list
fp
= xmalloc(sizeof(struct s_flist
));