delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2001/07/16/14:36:40

Date: Mon, 16 Jul 2001 21:34:02 +0300
From: "Eli Zaretskii" <eliz AT is DOT elta DOT co DOT il>
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

> From: "Juan Manuel Guerrero" <ST001906 AT HRZ1 DOT HRZ DOT TU-Darmstadt DOT De>
> 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  <eliz AT is DOT elta DOT co DOT il>

	* 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 <stdio.h>
 
+#include <fcntl.h>
+#ifndef O_BINARY
+# ifdef _O_BINARY
+#  define O_BINARY _O_BINARY
+#  define setmode  _setmode
+# endif
+#endif
+#ifdef O_BINARY
+# include <io.h>
+#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 <sys/types.h>
+# include <sys/stat.h>
+# 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;

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019