delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2000/11/07/13:01:52

From: pavenis AT lanet DOT lv
To: Eli Zaretskii <eliz AT delorie DOT com>, djgpp-workers AT delorie DOT com
Date: Tue, 7 Nov 2000 20:01:22 +0200
MIME-Version: 1.0
Subject: Re: Patch for dtou.c and utod.c
CC: Daniel Taupin <taupin AT lps DOT u-psud DOT fr>
Message-ID: <3A085F92.13312.15B43A4@localhost>
In-reply-to: <200005132122.RAA16253@indy.delorie.com>
References: <00051313422100 DOT 25039 AT hal> (message from Andris Pavenis on Sat, 13 May 2000 13:35:51 +0200)
X-mailer: Pegasus Mail for Win32 (v3.12c)
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

--Message-Boundary-4505
Content-type: text/plain; charset=US-ASCII
Content-transfer-encoding: 7BIT
Content-description: Mail message body

A long time have gone since I sent previous patches

On 13 May 2000, at 17:22, Eli Zaretskii wrote:

> I have several comments:
> 
> > !   strcpy (tfname, fname);
> > !   for (bn=w=tfname; *w; w++) 
> > !     if (*w=='/' || *w=='\\') 
> > !       bn = w+1;  
> > !   if (bn) *bn=0;
> > !   strcat (tfname,"utod.tm$");
> 
> This fragment from dtou.c doesn't seem to cover the case of "d:foo".
> (A similar problem exists in utod.c.)

OK. I added test for ':'. Perhaps it's best to leave multiple ':'s in name 
for DOS (it's illegal anyway so DOS will complain ...)

> 
> >     while ((l=read(sf, buf, 16384)) > 0)
> > !   { 
> > !     for (i=k=0; i<l; i++) 
> > !       if (buf[i]!=13)
> > !         buf[k++]=buf[i];
> > !     l2=write(df, buf, k);
> > !     if (l2<0) break;
> > !     if (l2!=k) { err=1; break; }
> > !   }
> 
> If you open the file in binary mode, it would make sense to handle the
> case of a lone CR character (without an LF right after it), instead of
> removing it, like the library does.  Also, you need to handle the case
> of trailing ^Z characters (done by the library in the current
> version).

Tried to do that (including truncating file on ^Z).

> 
> >     while ((l=read(sf, buf, 16384)) > 0)
> > !   {
> > !     int iscr=0;
> > !     for (i=k=0; i<l; i++)
> > !     {
> > !       if (buf[i]==10 && !iscr) buf2[k++]=13;
> > !       iscr=buf[i]==13 ? 1 : 0;
> > !       buf2[k++]=buf[i];
> > !     }
> 
> This doesn't seem to handle the case when the buffer read from the
> input file happens to end with a CR, whose LF is in the next
> buffer-ful (because the value of iscr is reset after each call to
> `read').

Moved definition outside the loop. That should fix this problem

I did only some minimal testing yet.

Andris






--Message-Boundary-4505
Content-type: text/plain; charset=US-ASCII
Content-transfer-encoding: 7BIT
Content-description: Text from file 'utils.diff'

--- src/utils/utod.c~1	Thu Jun  3 20:27:42 1999
+++ src/utils/utod.c	Tue Nov  7 19:49:44 2000
@@ -1,31 +1,48 @@
+/* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+/* Modified by A.Pavenis to work also in different Unix clones */
 #include <stdio.h>
-#include <dir.h>
-#include <dos.h>
 #include <fcntl.h>
 #include <sys/stat.h>
-#include <unistd.h>
-#include <string.h>
 #include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <utime.h>
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
 
 static int
 utod(char *fname)
 {
-  int sf, df, l;
-  struct ftime ftime;
-  char buf[16384];
-  char tfname[MAXPATH], drive[3], path[MAXPATH];
-  sf = open(fname, O_RDONLY|O_TEXT);
+  int i, k, k2, sf, df, l, l2, err=0, iscr=0;
+  char buf[16384], buf2[32768];
+  char tfname[FILENAME_MAX], *bn, *w;
+  struct stat st;
+  struct utimbuf tim1;
+  sf = open(fname, O_RDONLY|O_BINARY);
   if (sf < 0)
   {
     perror(fname);
     return 1;
   }
-  fnsplit(fname, drive, path, NULL, NULL);
-  fnmerge(tfname, drive, path, "utod", "tm$");
-  df = open(tfname, O_WRONLY|O_CREAT|O_TRUNC|O_TEXT, 0644);
+
+  fstat (sf,&st);
+  tim1.actime = st.st_atime;
+  tim1.modtime = st.st_mtime;
+
+  strcpy (tfname, fname);
+  for (bn=w=tfname; *w; w++) 
+    if (*w=='/' || *w=='\\' || *w==':') 
+      bn = w+1;  
+  if (bn) *bn=0;
+  strcat (tfname,"utod.tm$");
+  
+  df = open(tfname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644);
   if (df < 0)
   {
     perror(tfname);
@@ -34,15 +51,37 @@
   }
 
   while ((l=read(sf, buf, 16384)) > 0)
-    write(df, buf, l);
+  {
+    for (i=k=0; i<l; i++)
+    {
+      if (buf[i]==10 && !iscr) buf2[k++]=13;
+      iscr=(buf[i]==13 ? 1 : 0);
+      buf2[k++]=buf[i];
+    }
+    l2=write(df, buf2, k);
+    if (l2<0) break;
+    if (l2!=k) { err=1; break; }
+  }
+
+  if (l<0) perror (fname);
+  if (l2<0) perror (tfname);
+  if (err) fprintf (stderr,"Cannot process file %s\n",fname);
 
-  getftime(sf, &ftime);
-  setftime(df, &ftime);
   close(sf);
   close(df);
 
-  remove(fname);
-  rename(tfname, fname);
+  if (l>=0 && l2>=0 && err==0)
+  {
+    remove(fname);
+    rename(tfname, fname);
+    utime(fname, &tim1);
+    chown(fname, st.st_uid, st.st_gid);
+    chmod(fname, st.st_mode);
+  }
+  else 
+  {
+    remove(tfname);
+  }
   return 0;
 }
 
--- src/utils/dtou.c~1	Thu Jun  3 20:27:42 1999
+++ src/utils/dtou.c	Tue Nov  7 19:49:18 2000
@@ -1,29 +1,45 @@
+/* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+/* Modified by A.Pavenis to work also in different Unix clones */
 #include <stdio.h>
-#include <dir.h>
-#include <dos.h>
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <utime.h>
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
 
 static int
 dtou(char *fname)
 {
-  int sf, df, l;
+  int i, k, k2, sf, df, l, l2, err=0, isCR=0;
   char buf[16384];
-  char tfname[MAXPATH], drive[3], path[MAXPATH];
-  struct ftime ftime;
-  sf = open(fname, O_RDONLY|O_TEXT);
+  char tfname[FILENAME_MAX], *bn, *w;
+  struct stat st;
+  struct utimbuf tim1;
+  sf = open(fname, O_RDONLY|O_BINARY);
   if (sf < 1)
   {
     perror(fname);
     return 1;
   }
-  fnsplit(fname, drive, path, NULL, NULL);
-  fnmerge(tfname, drive, path, "utod", "tm$");
+  
+  fstat (sf,&st);
+  tim1.actime = st.st_atime;
+  tim1.modtime = st.st_mtime;
+
+  strcpy (tfname, fname);
+  for (bn=w=tfname; *w; w++) 
+    if (*w=='/' || *w=='\\' || *w==':') 
+      bn = w+1;  
+  if (bn) *bn=0;
+  strcat (tfname,"utod.tm$");
+  
   df = open(tfname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644);
   if (df < 1)
   {
@@ -32,16 +48,42 @@
     return 1;
   }
 
+  k2=0;
   while ((l=read(sf, buf, 16384)) > 0)
-    write(df, buf, l);
+  { 
+    int CtrlZ=0;
+    for (i=k=0; i<l; i++) 
+      {
+         if (isCR && buf[i]!=0x0A) buf[k++] = 0x0D; 
+         if (buf[i]==0x0D) { isCR=1; continue; }
+         if (buf[i]==0x1A) { CtrlZ=1; break; }
+         	     else    buf[k++] = buf[i];
+         isCR = 0;
+      }
+    if (k>0) l2=write(df, buf, k);
+    if (l2<0 || CtrlZ) break;
+    if (l2!=k) { err=1; break; }
+  }
+
+  if (l<0) perror (fname);
+  if (l2<0) perror (tfname);
+  if (err) fprintf (stderr,"Cannot process file %s\n",fname);
 
-  getftime(sf, &ftime);
-  setftime(df, &ftime);
   close(sf);
   close(df);
 
-  remove(fname);
-  rename(tfname, fname);
+  if (l>=0 && l2>=0 && err==0)
+  {
+    remove(fname);
+    rename(tfname, fname);
+    utime(fname, &tim1);
+    chown(fname, st.st_uid, st.st_gid);
+    chmod(fname, st.st_mode);
+  }
+  else 
+  {
+    remove(tfname);
+  }
   return 0;
 }
 
@@ -53,3 +95,4 @@
     rv += dtou(*argv);
   return rv;
 }
+

--Message-Boundary-4505--

- Raw text -


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