Date: Mon, 16 Jul 2001 21:34:02 +0300 From: "Eli Zaretskii" Sender: halo1 AT zahav DOT net DOT il To: ST001906 AT HRZ1 DOT HRZ DOT TU-Darmstadt DOT De Message-Id: <3405-Mon16Jul2001213401+0300-eliz@is.elta.co.il> X-Mailer: Emacs 20.6 (via feedmail 8.3.emacs20_6 I) and Blat ver 1.8.9 CC: djgpp-workers AT delorie DOT com In-reply-to: <17DE8095C8F@HRZ1.hrz.tu-darmstadt.de> (ST001906 AT HRZ1 DOT HRZ DOT TU-Darmstadt DOT De) Subject: Re: ports of gnu alpha packages References: <4CB8EA3789 AT HRZ1 DOT hrz DOT tu-darmstadt DOT de> (ST001906 AT HRZ1 DOT HRZ DOT TU-Darmstadt DOT De) <17DE8095C8F AT HRZ1 DOT hrz DOT tu-darmstadt DOT de> Reply-To: djgpp-workers AT delorie DOT com Errors-To: nobody AT delorie DOT com X-Mailing-List: djgpp-workers AT delorie DOT com X-Unsubscribes-To: listserv AT delorie DOT com Precedence: bulk > From: "Juan Manuel Guerrero" > Date: Mon, 16 Jul 2001 16:26:22 +0200 > > > > I have Sed 3.02.80 ported, too. I also added to it a feature whereby > > Sed no longer reads in text mode. This makes it possible to support > > files with embedded ^Z and lone ^M characters. > > > > I sent the diffs to the Sed maintainer, but didn't hear from him yet, > > although this was long ago. > > Would be nice to have this feature available for all djgpp users. > If you send the patch to me I will apply it. Attached. 2000-01-01 Eli Zaretskii * sed/utils.h: Include fcntl.h. (O_BINARY, setmode): Define if O_BINARY is undefined. [O_BINARY]: Include io.h. (set_read_mode): Declare a prototype. * sed/utils.c [O_BINARY]: Include sys/stat.h and make sure S_ISCHR is defined. (set_read_mode): New function, switches a stream into binary mode. This is a no-op unless O_BINARY is defined. (ck_fwrite) [O_BINARY]: If we are writing to a character device, replace every ^Z character with an ASCII string "^Z". * sed/execute.c (line_undosify): New function, a no-op unless O_BINARY is defined. (read_mem_line, read_file_line): Call line_undosify to remove a trailing ^M or ^Z from a line. (dump_append_queue): Call set_read_mode. [O_BINARY]: Remove ^M, if before the newline, and ^Z, if immediately before EOF. (open_next_file): Call set_read_mode. --- sed/utils.h~0 Mon Jul 6 06:56:26 1998 +++ sed/utils.h Fri Dec 31 21:47:08 1999 @@ -1,7 +1,19 @@ #include +#include +#ifndef O_BINARY +# ifdef _O_BINARY +# define O_BINARY _O_BINARY +# define setmode _setmode +# endif +#endif +#ifdef O_BINARY +# include +#endif + void panic P_((const char *str, ...)); +void set_read_mode P_((FILE *stream)); FILE *ck_fopen P_((const char *name, const char *mode)); void ck_fwrite P_((const VOID *ptr, size_t size, size_t nmemb, FILE *stream)); size_t ck_fread P_((VOID *ptr, size_t size, size_t nmemb, FILE *stream)); --- sed/utils.c~0 Tue Sep 7 02:37:52 1999 +++ sed/utils.c Sat Jan 1 11:32:12 2000 @@ -62,6 +62,14 @@ # endif /* RX_MEMDBUG */ #endif /* HAVE_STDLIB_H */ +#ifdef O_BINARY +# include +# include +# ifndef S_ISCHR +# define S_ISCHR(m) (((m)&S_IFMT) == S_IFCHR) +# endif +#endif + const char *myname; @@ -132,6 +140,21 @@ utils_fp_name(fp) return "{Unknown file pointer}"; } +void +set_read_mode (fp) + FILE *fp; +{ +#ifdef O_BINARY + /* For systems that distinguish between text and binary files, + switch all input streams to binary mode. This is so we get all + the characters from the file, instead of relying on the + misfeatures of the C library conversions (e.g., most of them drop + lone ^M characters, stop at the first ^Z character, etc.) */ + if (!isatty(fileno(fp))) + setmode(fileno (fp), O_BINARY); +#endif +} + /* Panic on failing fopen */ FILE * ck_fopen(name, mode) @@ -170,15 +193,44 @@ ck_fwrite(ptr, size, nmemb, stream) size_t nmemb; FILE *stream; { - if (size && fwrite(ptr, size, nmemb, stream) != nmemb) + size_t written; +#ifdef O_BINARY + struct stat st; + + if (!size) + return; + if (fstat(fileno(stream), &st) == 0 && S_ISCHR(st.st_mode)) { - if (nmemb==1) - panic(_("couldn't write an item to %s: %s"), - utils_fp_name(stream), strerror(errno)); - else - panic(_("couldn't write %d items to %s: %s"), - nmemb, utils_fp_name(stream), strerror(errno)); + char *p; + size_t left = nmemb*size; + + /* Text-mode writes to character devices stop at the first ^Z + character. Repair this lossage. */ + while ((p = memchr(ptr, 0x1a, left)) != NULL) + { + size_t this_write = p - (char *)ptr; + + if (fwrite(ptr, 1, this_write, stream) != this_write) + break; + fwrite("^Z", 1, 2, stream); + left -= this_write + 1; + ptr = (char *)ptr + this_write + 1; + } + if (p == NULL && fwrite(ptr, 1, left, stream) == left) + return; } + else +#endif + + if (!size || fwrite(ptr, size, nmemb, stream) == nmemb) + return; + + if (nmemb==1) + panic(_("couldn't write an item to %s: %s"), + utils_fp_name(stream), strerror(errno)); + else + panic(_("couldn't write %d items to %s: %s"), + nmemb, utils_fp_name(stream), strerror(errno)); } /* Panic on failing fread */ --- sed/execute.c~0 Tue Sep 7 02:37:32 1999 +++ sed/execute.c Sat Jan 1 12:09:08 2000 @@ -263,6 +263,21 @@ line_exchange(a, b) MEMCPY( b, &t, sizeof(struct line)); } +static void line_undosify P_((struct line *, size_t, int)); +static void +line_undosify(lbuf, from, ch) + struct line *lbuf; + size_t from; +{ +#ifdef O_BINARY + size_t lbuf_len = lbuf->length; + + /* Remove character CH from the end of the line starting at offset FROM. */ + if (lbuf_len > from && lbuf->text[lbuf_len-1] == ch) + lbuf->length--; +#endif +} + /* dummy function to simplify read_pattern_space() */ static flagT read_always_fail P_((struct input *)); @@ -302,6 +317,7 @@ read_mem_line(input) } str_append(&line, input->cur, l); + line_undosify(&line, line.length - l, '\r'); input->left -= e - input->cur; input->cur = e; return 1; @@ -361,6 +377,7 @@ read_file_line(input) if (buffer.length == 0) { + line_undosify(&line, initial_length, 0x1a); if (!*input->file_list && !POSIXLY_CORRECT) line.chomped = 0; /* Did we hit EOF without reading anything? If so, try @@ -372,6 +389,7 @@ read_file_line(input) blen = b - buffer.active; str_append(&line, buffer.active, blen); + line_undosify(&line, line.length - blen, '\r'); ++blen; buffer.active += blen; buffer.length -= blen; @@ -449,8 +467,52 @@ dump_append_queue() no error condition." IEEE Std 1003.2-1992 */ if (fp) { + set_read_mode(fp); while ((cnt = ck_fread(buf, 1, sizeof buf, fp)) > 0) - ck_fwrite(buf, 1, cnt, stdout); + { +#ifdef O_BINARY + /* Remove CRs from CR-LF pairs, and the trailing ^Z. */ + register char *s = buf, *d = buf; + register size_t len = cnt; + + while (len--) + { + if (*s == '\r' || *s == 0x1a) + { + if (!len) + { + if (getc(fp) != EOF) + { + if (*s == '\r') + { + fseek(fp, -2L, SEEK_CUR); + cnt--; + } + else + { + fseek(fp, -1L, SEEK_CUR); + *d++ = *s++; + } + break; + } + else if (*s == 0x1a) + { + cnt--; + break; + } + } + else if (s[1] == '\n') + { + s++; + len--; + cnt--; + } + } + *d++ = *s++; + } +#endif + ck_fwrite(buf, 1, cnt, stdout); + } fclose(fp); } } @@ -483,6 +545,8 @@ open_next_file(name, input) return; } + set_read_mode (input->fp); /* for systems with text/binary schizophrenia */ + input->read_fn = read_file_line; if (force_unbuffered) input->no_buffering = 1;